You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拷贝赋值运算符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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 22:45:17