拷贝赋值运算符const参数修改指针指向值是否违反const规则?
问题解析:const对象为何能修改指针成员指向的内容
先看给出的代码:
class HasPtr { public: HasPtr(const string& s = string()) :ps(new string(s)), i(0), use(new size_t(1)) {} HasPtr(const HasPtr& p) :ps(p.ps), i(p.i), use(p.use) { ++*use; } HasPtr& operator=(const HasPtr&); ~HasPtr(); private: string* ps; int i; size_t* use; }; HasPtr& HasPtr::operator=(const HasPtr& rhs) { ++*rhs.use; if (--*use == 0) { delete ps; delete use; } ps = rhs.ps; i = rhs.i; use = rhs.use; return *this; }
问题核心:拷贝赋值运算符的参数const HasPtr& rhs是const类型,为何能执行++*rhs.use修改use指向的size_t值?这是否违反const属性规则?
关键区分:const对象的成员 vs 成员指向的对象
首先要明确const修饰的是对象本身,对于const HasPtr& rhs来说,规则限制的是不能修改rhs这个对象的成员本身,但不限制成员指向的外部对象(只要成员的类型允许修改指向内容)。
具体到这里:
- rhs是const HasPtr对象,它的
use成员是size_t*类型,在const对象中,这个成员会被视为size_t* const——也就是指针本身是只读的,不能让它指向另一个地址,但指针指向的size_t变量是可以修改的,因为这个size_t本身不是const类型。 ++*rhs.use操作的是rhs.use指向的那个size_t值,并没有修改rhs.use这个指针本身(比如没有给rhs.use赋值新的地址),所以完全符合const对象的规则。
结合《C++ Primer》的规则理解
《C++ Primer》说的“只能使用不会修改对象的操作”,这里的“修改对象”指的是修改对象自身的成员(比如修改rhs的i值,或者给rhs的ps/use指针重新赋值),而不是修改成员指向的外部数据。我们这里修改的是共享引用计数的那个size_t变量,不属于rhs对象本身的一部分,所以不违反规则。
内容的提问来源于stack exchange,提问作者gaofeng
相关产品推荐
相关产品推荐

