Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;常数正确性、易受攻击性或非预期使用?_C++_Const Correctness_Pimpl Idiom - Fatal编程技术网

C++ C++;常数正确性、易受攻击性或非预期使用?

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

我遗漏了一些东西,或者常量正确性与指针(或者可能是智能指针,因为这是我测试过的?)的预期不一样。总之,下面是我在尝试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{ 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正确性检查的目的不止这些。我想这是有道理的,它只检查指针,而不是它的内容,因为这可能是另一个指针,可能是指向另一个指针…等等,这将是太多的强制执行。嗯,这就清楚了。如果你愿意,你可以写下来作为答案,我会选择它。谢谢