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

通过std::weak_ptr间接修改const对象是否属于未定义行为?

关于自存weak_ptr实现类共享指针时的常量性丢失与未定义行为问题

我在检查代码时发现一种模拟std::enable_shared_from_this的旧实现:在类内部保存指向自身的std::weak_ptr,通过静态创建函数完成初始化,示例代码如下:

struct X {
    static auto create() {
        auto ret = std::shared_ptr<X>(new X);
        ret->m_weak = ret;
        return ret;
    }

    // 使用 m_weak.lock() 访问对象
    //... 
private:
    X() {}
    std::weak_ptr<X> m_weak;
};

随后我注意到这种实现存在常量性问题:

struct X {
    static auto create() {
        auto ret = std::shared_ptr<X>(new X);
        ret->m_weak = ret;
        return ret;
    }

    void indirectUpdate() const {
        m_weak.lock()->val = 1;
    }

    void print() const {
        std::cout << val << '\n';
    }

private:
    X() {}
    std::weak_ptr<X> m_weak;
    int val = 0;
};

int main() {
    auto x = X::create();
    x->print();
    x->indirectUpdate();
    x->print();
}

这段代码里,indirectUpdate()是const成员函数,按规则不应修改对象,但实际却能修改。原因是在const方法中,std::weak_ptr.lock()仍返回非const的std::shared_ptr<>,从而可以间接修改对象。而std::enable_shared_from_this不会有这个问题——它的shared_from_this在const方法中会返回指向const对象的shared_ptr。

我不确定这段代码是否属于未定义行为(UB),想寻求解答。


更新说明

之前的表述不够准确,我想说明的是:即使持有指向const对象的shared_ptr,也会通过这种方式丢失常量性,示例代码如下:

struct X {
    static auto create() {
        auto ret = std::shared_ptr<X>(new X);
        ret->m_weak = ret;
        return ret;
    }

    void show() const { std::cout << "const \n";}
    void show() { std::cout << "non-const\n";}

    void indirectUpdate() const {
        show();
        m_weak.lock()->show();
        m_weak.lock()->val = 1;
    }

    void print() const {
        std::cout << val << '\n';
    }

    int val = 0;

private:
    X() {}
    std::weak_ptr<X> m_weak;
};

int main() {
    // 这里持有const指针
    std::shared_ptr<const X> x = X::create();
    x->print();
    x->indirectUpdate();
    x->print();
}

程序输出为:

0
const 
non-const
1

可见常量性已丢失,想确认该行为是否属于未定义行为。


内容的提问来源于stack exchange,提问作者Afshin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:20:34