C++ const 正确性漏洞或意外使用?
Posted
技术标签:
【中文标题】C++ const 正确性漏洞或意外使用?【英文标题】:C++ const correctness vulerability or unintended usage? 【发布时间】:2013-06-09 05:22:34 【问题描述】:我遗漏了一些东西,或者 const-correctness 与指针(或者可能是智能指针,因为这是我测试过的?)的预期效果不太一样。无论如何,这是我在尝试 PIMPL 习语的变体时观察到的。
我声明了以下内容:
class A
public:
A(...);
...
bool update_stuff(...) const;
...
protected:
bool update_stuff_impl(...) const;
...
private:
struct pimpl;
pimpl* m_pimpl;
;
对于实施,我有类似的东西:
struct A::pimpl
pimpl(...): some_data(new some_type());
...
some_method1(...); // Modifies content of some_data
some_method2(...); // Modifies content of some_data
...
boost::shared_ptr<some_type> some_data;
;
A::A(...): m_pimpl(new pimpl(...))
...
bool A::update_stuff(...) const
if( !update_stuff_impl(...) )
return false;
return true;
bool A::update_stuff_impl(...) const
//-Change content of pimpl::some_data here
m_pimpl->some_method1(...);
m_pimpl->some_method2(...);
return true;
我无法理解的是,当我实际修改 A::pimpl::some_data
时,我如何能够摆脱对函数 A::update_stuff(...)
和 A::update_stuff_impl(...)
使用 const
限定符??!或者这是预期的行为还是只是简单的错误使用?如果是后者之一,如果您能确定如何纠正它,请不胜感激?
感谢您的时间和兴趣。
【问题讨论】:
由于您没有更改任何类成员,因此 const 正确性仍然存在,例如在 update_stuff_impl 中,您不会将指针 m_pimpl 更改为指向其他内容! 好的..就这样?我也是这么想的,但出于某种原因,我认为 const-correctness 检查的不止这些。我想它只检查指针而不是它的内容是有道理的,因为这可能是另一个指针,它可能指向另一个指针......等等,这将是太多的强制执行。嗯,这清除了它。如果你喜欢,你可以把它写成答案,我会选择它。谢谢。 You underestimate compilers. 【参考方案1】:这不是一个新发现,您可以阅读 C++ 中的“const is shallow”之类的内容。是什么导致了物理和 逻辑 const 之间的自然区别(也请在第二个之后阅读)。
如果您在课堂上有指针,无论是聪明的还是愚蠢的,您都可能涉及到这个问题并且必须仔细设计。考虑到修改指针另一端的附加数据没有被发现。
可能的解决方法是使指针变为 const T* 并添加返回 T* 的私有成员函数。另一个是一般限制对指针的直接访问,并且需要一对函数,一个是常量,另一个是非常量。
【讨论】:
【参考方案2】:C++ 保护pimpl* m_pimpl
变量的常量。它不允许更改指针的值。但它允许对这个指针指向的对象做任何事情。一般没有办法保护它。
例如,考虑一个类成员变量int a; int* b;
。在类成员函数中,我们可以执行以下操作:
int a_copy = a;
a_copy = 42;
int* b_copy = b;
*b_copy = 42;
这里的a_copy
和b_copy
是局部变量。它们不受您所在对象的 const 保护。因此可以使用 const 方法执行此代码。不同的是这里a
变量值没有改变,*b
值改变了。由于可以轻松复制指针,因此编译器无法知道某个指针是否等于位于 const 对象的成员值中的任何指针。
【讨论】:
以上是关于C++ const 正确性漏洞或意外使用?的主要内容,如果未能解决你的问题,请参考以下文章