为何std::shared_ptr{}未初始化指向对象,与int{}行为不同?
你的推论完全正确:std::shared_ptr<Foo> sharedFoo {}仅完成了shared_ptr自身的默认初始化,使其成为一个空智能指针(内部持有的原始指针为nullptr),并没有为Foo分配内存或调用其默认构造函数——这就是触发段错误的原因,你尝试通过空指针调用成员函数。
为什么和int i {}的表现不同?
- 对于
int这类标量类型,使用{}进行列表初始化时会触发值初始化。根据C++标准,标量类型的值初始化会将其置为零值:int变为0,指针变为nullptr,布尔值变为false等。 - 而
std::shared_ptr<T>是一个类模板,空大括号{}会调用它的默认构造函数。shared_ptr的设计职责是管理已有的动态分配对象,其默认构造函数的行为就是创建一个不指向任何对象的空智能指针,不会自动为模板参数类型分配内存。
如何用大括号初始化让shared_ptr指向默认构造的Foo?
如果你想通过大括号语法实现“让shared_ptr管理一个默认构造的Foo对象”,可以这样写:
// 推荐方式:用make_shared高效安全地分配对象 std::shared_ptr<Foo> sharedFoo { std::make_shared<Foo>() }; // 也可以显式创建对象(不推荐,不如make_shared高效) std::shared_ptr<Foo> sharedFoo { new Foo() };
问题参考代码
#include <memory> #include <iostream> class Foo { public: int getValue() const { return value; } private: int value = 0; }; int main() { int i {}; std::shared_ptr<Foo> sharedFoo { }; std::cout << i << std::endl; std::cout << sharedFoo->getValue() << std::endl; //SEGFAULT return 0; }
内容的提问来源于stack exchange,提问作者HarryP2023
相关产品推荐
相关产品推荐

