C++ C++;常数正确性、易受攻击性或非预期使用?
我遗漏了一些东西,或者常量正确性与指针(或者可能是智能指针,因为这是我测试过的?)的预期不一样。总之,下面是我在尝试PIMPL习语的一个变体时观察到的情况 本人声明如下:C++ C++;常数正确性、易受攻击性或非预期使用?,c++,const-correctness,pimpl-idiom,C++,Const Correctness,Pimpl Idiom,我遗漏了一些东西,或者常量正确性与指针(或者可能是智能指针,因为这是我测试过的?)的预期不一样。总之,下面是我在尝试PIMPL习语的一个变体时观察到的情况 本人声明如下: class A { public: A(...); ... bool update_stuff(...) const; ... protected: bool update_stuff_impl(...) const; ... private: struct pimpl; pimpl* m_pi
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{
pimpl(…):一些数据(新的一些类型());
...
some_method1(…);//修改某些_数据的内容
some_method2(…);//修改某些_数据的内容
...
boost::共享一些数据;
};
A::A(…):m_pimpl(新pimpl(…)){
...
}
boola::更新内容(…)常量{
如果(!update_stuff_impl(…)){
返回false;
}
返回true;
}
bool A::update_stuff_impl(…)const{
//-更改pimpl的内容::此处的一些_数据
m_pimpl->some_method1(…);
m_pimpl->some_method2(…);
返回true;
}
我很难理解的是,当我实际修改A::pimpl::一些数据时,我如何才能使用const
限定符来定义A::update_stuff(…)
和A::update_stuff_impl(…)
??!或者这是预期的行为,还是纯粹的坏习惯?如果是后一种情况,请确认如何纠正,谢谢
感谢您的时间和兴趣。C++保护pimpl*m_pimpl
变量的常量。它不允许更改指针的值。但它允许对指针指向的对象执行任何操作。一般来说,没有办法保护它
例如,考虑一个类成员变量<代码> int a;int*b代码>。在类成员函数中,我们可以执行以下操作:
int a_copy = a;
a_copy = 42;
int* b_copy = b;
*b_copy = 42;
这里的a\u copy
和b\u copy
是局部变量。它们不会受到你所在物体的保护。因此,可以使用const方法执行此代码。不同之处在于,a
变量值在此未更改,*b
值已更改。由于指针很容易复制,编译器无法知道某个指针是否等于常量对象成员值中的任何指针。C++保护pimpl*m_pimpl
变量的常量。它不允许更改指针的值。但它允许对指针指向的对象执行任何操作。一般来说,没有办法保护它
例如,考虑一个类成员变量<代码> int a;int*b代码>。在类成员函数中,我们可以执行以下操作:
int a_copy = a;
a_copy = 42;
int* b_copy = b;
*b_copy = 42;
这里的a\u copy
和b\u copy
是局部变量。它们不会受到你所在物体的保护。因此,可以使用const方法执行此代码。不同之处在于,a
变量值在此未更改,*b
值已更改。由于指针可以很容易地被复制,所以编译器无法知道某个指针是否等于任何指向const对象成员值的指针。 这不是一个新发现,你可以在C++中读到“const是浅的”之类的东西。什么导致物理常数和逻辑常数之间的自然区别(也在第二个之后阅读)
若你们在类中有指针,不管它是聪明的还是愚蠢的,你们很可能卷入了这个问题,必须仔细设计。考虑到未发现修改指针另一端的附加数据
可能的解决方法是将指针设为常量T*并添加返回T*的私有成员函数。另一个是限制对指针的直接访问,一般需要一对函数,一个const和其他非const .< /p> < p>这不是一个新发现,你可以在C++中读到一些类似“const是浅的”的东西。什么导致物理常数和逻辑常数之间的自然区别(也在第二个之后阅读)
若你们在类中有指针,不管它是聪明的还是愚蠢的,你们很可能卷入了这个问题,必须仔细设计。考虑到未发现修改指针另一端的附加数据
可能的解决方法是将指针设为常量T*并添加返回T*的私有成员函数。另一种方法是限制对指针的直接访问,通常需要一对函数,一个是常量,另一个是非常量。由于您没有更改任何类成员,常量正确性仍然有效,例如在update_stuff_impl中,您没有更改指针m_pimpl以指向其他对象!好的,就这样?我也是这么想的,但出于某种原因,我认为const正确性检查的目的不止这些。我想这是有道理的,它只检查指针,而不是它的内容,因为这可能是另一个指针,可能是指向另一个指针…等等,这将是太多的强制执行。嗯,这就清楚了。如果你愿意,你可以写下来作为答案,我会选择它。谢谢。由于您没有更改任何类成员,常量正确性仍然有效。例如,在update_stuff_impl中,您没有更改指向其他对象的指针m_pimpl!好的,就这样?我也是这么想的,但出于某种原因,我认为const正确性检查的目的不止这些。我想这是有道理的,它只检查指针,而不是它的内容,因为这可能是另一个指针,可能是指向另一个指针…等等,这将是太多的强制执行。嗯,这就清楚了。如果你愿意,你可以写下来作为答案,我会选择它。谢谢