简体   繁体   English

C ++ const正确性的有效性或无意的用法?

[英]C++ const correctness vulerability or unintended usage?

I am missing something or const-correctness doesn't work quite as intended with pointers (or perhaps smart pointers since that is what I've tested?). 我缺少一些东西或const-correctness不能像指针一样工作(或者也许智能指针,因为那是我测试过的?)。 Anyway, here is what I observed with trying out a variant of the PIMPL idiom. 无论如何,这是我在尝试使用PIMPL习语的变体时所观察到的。

I have the following declared: 我声明了以下内容:

class A {
public:
  A(...);
  ...
  bool update_stuff(...) const;
  ...
protected:
  bool update_stuff_impl(...) const;
  ...
private:
  struct pimpl;
  pimpl* m_pimpl;
};

And for the implementation, I have something like: 为了实现,我有类似的东西:

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;
}

What I'm having trouble understanding is how I could get away with using const qualifier for the functions A::update_stuff(...) and A::update_stuff_impl(...) when I am actually modifying A::pimpl::some_data ??! 我无法理解的是当我实际修改A::pimpl::some_data A::update_stuff_impl(...)时,我如何能够使用const限定符来使用函数A::update_stuff(...)A::update_stuff_impl(...) A::pimpl::some_data ??! Or is this expected behavior or just plain bad usage? 或者这是预期的行为还是仅仅是错误的使用? If it is one of the latter, appreciate if you can identify how it can be corrected? 如果它是后者之一,请欣赏它是否可以确定如何纠正?

Thanks for your time and interest. 感谢您的时间和兴趣。

C++ protects constness of pimpl* m_pimpl variable. C ++保护pimpl* m_pimpl变量的pimpl* m_pimpl It doesn't allow to change the value of the pointer. 它不允许更改指针的值。 But it allows to do anything with the object this pointer is pointing. 但它允许对此指针指向的对象执行任何操作。 Generally there is no way to protect it. 一般来说,没有办法保护它。

For example, consider a class member variables int a; int* b; 例如,考虑一个类成员变量int a; int* b; int a; int* b; . In a class member function we can do the following: 在类成员函数中,我们可以执行以下操作:

int a_copy = a;
a_copy = 42;
int* b_copy = b;
*b_copy = 42;

Here a_copy and b_copy are local variables. 这里a_copyb_copy是局部变量。 They are not protected with constness of the object you're in. So this code can be executed using const method. 它们不受您所在对象的常量保护。因此,此代码可以使用const方法执行。 The difference is that a variable value has not been changed here, and *b value has been changed. 不同的是, a变量值尚未改变了这里,和*b值已经改变。 Since a pointer can be easily copied, there is no way for a compiler to know if some pointer is equal to any pointer lying in a member value of const object. 由于可以轻松复制指针,因此编译器无法知道某个指针是否等于位于const对象的成员值中的任何指针。

It's not a new discovery, you can read up on something like 'const is shallow' in C++. 这不是一个新发现,你可以在C ++中阅读类似'const is shallow'的内容。 What leads to natural distinction between physical and logical const (read after the second too). 什么导致物理和逻辑 const之间的自然区别(在第二个之后读取)。

If you have pointer in class, be it smart or dumb, you're likely involved in this problem and must carefully design. 如果你在课堂上有指针,无论是聪明还是愚蠢,你可能都会遇到这个问题并且必须仔细设计。 Taking into account that modifying the attached data on the other end of pointer is not discovered. 考虑到未发现修改指针另一端的附加数据。

Possible workararounds are to make the pointer const T* and add private member function that returns T*. 可能的workararounds是使指针const T *并添加返回T *的私有成员函数。 Another is to restrict direct access to the pointer in general, and require a pair of functions one const and other nonconst. 另一种是通常限制对指针的直接访问,并且需要一对const和其他nonconst的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM