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

如何为传入的nullptr分配对象并在函数外访问?

函数内创建的std::shared_ptr无法在外部访问的解决方法

首先看原始代码:

struct MyObject {
  std::string name;
};

void getOrCreateMyObject(std::shared_ptr<MyObject> myObj) {
  if (myObj == nullptr) {
    myObj = std::make_shared<MyObject>();
    myObj->name = "Created Automatically";
  }
  std::cout << myObj->name << std::endl;
}

int main() {
  std::shared_ptr<MyObject> moPtr = nullptr;
  getOrCreateMyObject(moPtr);
  if (moPtr != nullptr) {
    std::cout << moPtr->name << std::endl;
  }
}

问题现象

传入nullptr的shared_ptr到函数后,函数内成功创建对象并输出名称,但返回main函数后,moPtr仍然是nullptr,无法访问新创建的对象。

问题原因

这是因为函数参数采用了值传递:std::shared_ptr作为参数传递时,会生成一个对象副本。函数内对这个副本的赋值操作,只会修改副本本身,不会影响外部的原始shared_ptr变量。

解决方案

有两种常用方式可以让外部访问到函数内创建的对象:

1. 使用引用传递修改原始对象

将函数参数改为std::shared_ptr<MyObject>&(引用类型),这样函数内的操作直接作用于原始的shared_ptr变量,修改会同步到外部。

修改后的函数定义:

void getOrCreateMyObject(std::shared_ptr<MyObject>& myObj) {
  if (myObj == nullptr) {
    myObj = std::make_shared<MyObject>();
    myObj->name = "Created Automatically";
  }
  std::cout << myObj->name << std::endl;
}

这种方式就是你补充说明中提到的修改方案,能直接解决问题。

2. 返回创建后的std::shared_ptr

让函数返回处理后的shared_ptr,在main函数中接收返回值,也能获取到新创建的对象:

修改后的完整代码:

#include <iostream>
#include <memory>
#include <string>

struct MyObject {
  std::string name;
};

std::shared_ptr<MyObject> getOrCreateMyObject(std::shared_ptr<MyObject> myObj) {
  if (myObj == nullptr) {
    myObj = std::make_shared<MyObject>();
    myObj->name = "Created Automatically";
  }
  std::cout << myObj->name << std::endl;
  return myObj;
}

int main() {
  std::shared_ptr<MyObject> moPtr = nullptr;
  moPtr = getOrCreateMyObject(moPtr);
  if (moPtr != nullptr) {
    std::cout << moPtr->name << std::endl;
  }
}

补充说明

你之前的误解在于:认为传递指针(或智能指针)会自动同步外部变量,但实际上这里是智能指针对象的值传递,而非指针的传递,因此副本的修改不会影响原始对象。使用引用传递可以让函数直接操作原始变量,从而解决问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:50:39