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

如何正确存储并使用shared_ptr地址以修改外部智能指针对象?

问题:shared_ptr修改无法同步到CommandManager的全局对象

我尝试传递一个可能为空的shared_ptr<MyObject>对象,期望在Command类中操作或创建CommandManager中的globalObj,但当前代码虽传递了地址,修改却无法同步到CommandManager中。以下是我的代码:

#include <iostream>
#include <memory>

struct MyObject {
  int i = 0;
  MyObject(const int i_) : i(i_) {}
};

struct Command {
  std::shared_ptr<MyObject> cmdObj;

  Command(std::shared_ptr<MyObject>& obj) : cmdObj(obj) {
    std::cout << "Store and use this address: " << &obj << std::endl;  // [1]
  }

  void execute() {
    if (cmdObj == nullptr) {
      cmdObj = std::make_shared<MyObject>(42);
    } else {
      cmdObj->i = 7;
    }
  }
};

struct CommandManager {
  std::shared_ptr<MyObject> globalObj;  // [1]

  CommandManager() { globalObj = nullptr; }

  void runCommand() {
    Command cmd(globalObj);
    cmd.execute();
  }
};

int main() {
  CommandManager cm;
  std::cout << "cm.globalObj address: " << &cm.globalObj << std::endl;  // [1]
  cm.runCommand();
  if (cm.globalObj == nullptr) {
    std::cout << "globalObj is null" << std::endl;
  } else {
    std::cout << "globalObj is " << cm.globalObj->i << std::endl;
  }
}

解决方案

问题核心:当前Command里的cmdObj是shared_ptr的独立副本,修改这个副本只会改变自身指向,不会影响原globalObj。要实现同步修改,必须直接操作原shared_ptr对象本身,而非它的副本。

方法1:使用shared_ptr的引用(推荐)

将Command中的cmdObj改为引用类型,这样所有操作都会直接作用于原globalObj:

#include <iostream>
#include <memory>

struct MyObject {
  int i = 0;
  MyObject(const int i_) : i(i_) {}
};

struct Command {
  // 修改为引用类型
  std::shared_ptr<MyObject>& cmdObj;

  // 构造函数初始化引用
  Command(std::shared_ptr<MyObject>& obj) : cmdObj(obj) {
    std::cout << "Store and use this address: " << &obj << std::endl;
  }

  void execute() {
    if (cmdObj == nullptr) {
      // 直接修改原shared_ptr的指向
      cmdObj = std::make_shared<MyObject>(42);
    } else {
      cmdObj->i = 7;
    }
  }
};

struct CommandManager {
  std::shared_ptr<MyObject> globalObj;

  CommandManager() { globalObj = nullptr; }

  void runCommand() {
    Command cmd(globalObj);
    cmd.execute();
  }
};

int main() {
  CommandManager cm;
  std::cout << "cm.globalObj address: " << &cm.globalObj << std::endl;
  cm.runCommand();
  if (cm.globalObj == nullptr) {
    std::cout << "globalObj is null" << std::endl;
  } else {
    std::cout << "globalObj is " << cm.globalObj->i << std::endl;
  }
}

方法2:使用shared_ptr的指针

如果Command需要长期持有对象(引用可能存在生命周期失效风险),可以存储指向shared_ptr的指针:

#include <iostream>
#include <memory>

struct MyObject {
  int i = 0;
  MyObject(const int i_) : i(i_) {}
};

struct Command {
  // 修改为指针类型
  std::shared_ptr<MyObject>* cmdObj;

  Command(std::shared_ptr<MyObject>& obj) : cmdObj(&obj) {
    std::cout << "Store and use this address: " << &obj << std::endl;
  }

  void execute() {
    if (*cmdObj == nullptr) {
      // 通过指针修改原shared_ptr的指向
      *cmdObj = std::make_shared<MyObject>(42);
    } else {
      (*cmdObj)->i = 7;
    }
  }
};

struct CommandManager {
  std::shared_ptr<MyObject> globalObj;

  CommandManager() { globalObj = nullptr; }

  void runCommand() {
    Command cmd(globalObj);
    cmd.execute();
  }
};

int main() {
  CommandManager cm;
  std::cout << "cm.globalObj address: " << &cm.globalObj << std::endl;
  cm.runCommand();
  if (cm.globalObj == nullptr) {
    std::cout << "globalObj is null" << std::endl;
  } else {
    std::cout << "globalObj is " << cm.globalObj->i << std::endl;
  }
}

两种方法运行后都会输出globalObj is 42,说明修改已同步到CommandManager的globalObj中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:55:19