我现在使用3ds max SDK工作的时间更长,几乎所有部分都没有使用const
。因此即使Width()
的{{1}}或Height()
获取者也未被标记为Bitmap
。这在小型项目中已经是一个真正的烦恼,但由于我一直在研究一个更大的项目,它变得越来越可怕。
例如,出于性能原因,我在多个类实例中持有单个const
实例作为Bitmap
成员。当然,有些情况我想通过一切实例来避免单个实例更改所有实例的属性,因此所有原始指针获取器(SDK所必需的)都会传递shared_ptr<Bitmap>
。不幸的是,现在我甚至无法询问const Bitmap*
的宽度 - 因为const Bitmap*
是非常量的。
我问自己,解决这个问题的最佳方法是什么。我看到三个选项:
Width()
。那将是很多地方,阅读起来非常糟糕。const_cast
方法。这会将所有const
封装在一个地方,也适用于其他项目。我被警告(我知道)这可能是基于意见的。但是我现在很长时间不得不处理这个恼人的问题,我真的很想找到一个解决方案,因此需要其他人的经验。
答案 0 :(得分:3)
首先,我想提一下,const
正确性的缺失可能因实现细节而合理,例如getter函数可能会对内部同步原语执行锁定,因此总是会改变内部状态而无法标记作为const
:
int Bitmap::Width(void)
{
int width{};
::std::lock_guard<::std::mutex> const lock{m_sync};
width = m_width;
return width;
}
作为一种解决方法,您可以编写专用的PImpl位图包装器,限制使用适当的const
限定符直接访问感兴趣的位图实现转发函数:
class SharedBitmap
{
private: ::std::shared_ptr<Bitmap> m_p_bitmap;
public: int Width(void) const
{
return m_p_bitmap->Width();
}
// other methods...
};
请注意,此方法与有问题的第三个选项不同,因为它不涉及const_cast
。
答案 1 :(得分:1)
根据我的经验(10年代),“const”一直是一个比它更有帮助的更大的因素。不要提到代码越来越长,因此难以阅读。如果您想知道库是如何工作的,那么无论如何都要阅读手册,而不是标题。如果您想知道自己做得对,那就进行功能测试。地狱甚至有静态分析工具检查变量是否被写入,而没有使用无用的非功能元数据来加载代码以捕获未记录的使用模式。而且由于有很多方法可以破坏const,因此它是捕获此类错误的正确方法。
总之,在我看来,选项1是最有效的解决方案。 (这是一种观点吗?那些不同意的人可能会这么认为。)
对于const的快速清除后,您可以#define const
甚至-Dconst
删除它,但是否安全可能取决于您的具体情况, illegal use正在为标准标头执行此操作。我做了类似#define private|protected public
的类似黑客,而不是在做白盒测试时弄乱friend
,就像魅力一样!
知道“常量变量”的概念在许多编程语言中都是无效的,如果没有它,它们似乎就可以了。
你需要const的唯一时间是C字符串常量/字符串文字。但是,似乎不是你的情况。