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

通过智能指针修改C++类成员变量失效问题咨询

问题解析:为什么智能指针修改不生效,普通指针却可以?

嘿,这个问题其实是对getNameUnique()函数返回值的本质理解不到位,咱们来一步步理清楚:

核心原因:getNameUnique()返回的是拷贝对象的智能指针

看一下你的getNameUnique()实现:

unique_ptr<string> getNameUnique() {
    return make_unique<string>(this->name);
}

这里的make_unique<string>(this->name)做了一件关键的事:创建一个全新的std::string对象,把this->name的内容拷贝到这个新对象里,然后返回指向这个新对象的unique_ptr。

也就是说,你拿到的nameUniquePtr指向的根本不是mary对象里的name成员,而是一个完全独立的、在堆上新建的字符串副本。所以你修改*nameUniquePtr的时候,只是修改了这个副本的值,和mary.name没有任何关系——这就是为什么调试时看到两个地址不一样,输出里原成员没变化的原因。

为什么普通指针getNamePtr()能生效?

再看getNamePtr()的实现:

string* getNamePtr() {
    return &name;
}

这个函数直接返回了mary.name成员变量的内存地址,你拿到的指针直接指向mary对象里的那个string。所以通过这个指针修改值,就是直接操作mary.name的内存,自然会看到原对象的成员被改变。

额外提醒:不要试图返回指向类成员的unique_ptr

如果你想让智能指针能修改原成员,可能会想改成:

// 绝对不要这么做!
unique_ptr<string> getNameUnique() {
    return unique_ptr<string>(&this->name);
}

这是严重错误的!因为unique_ptr的职责是管理对象的所有权,当它被销毁时会自动调用delete释放指向的内存。但this->name是Student对象的成员,它的内存是和Student对象一起分配的(要么在栈上,要么在堆上作为Student的一部分),Student对象销毁时会自动处理这个成员的内存。如果返回指向它的unique_ptr,最后会导致双重释放的未定义行为。

如果需要通过指针修改原成员,直接用普通指针、引用,或者返回string&会更合适。

内容的提问来源于stack exchange,提问作者Gary C.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:51:11