为何拷贝构造函数未被调用?C++ shared_ptr相关问题
问题原因分析
你编写的C++代码如下:
#include <iostream> #include <memory> using namespace std; class Init { private: int x; public: Init(int y) { x = y; cout << "default constructor called" << endl; } Init(std::shared_ptr<Init> z) { this->x = z->x; cout << "copy constructor called" << endl; } }; int main() { int k = 5; std::shared_ptr<Init> a = std::make_shared<Init>(k); std::shared_ptr<Init> b(a); return 0; }
你原本预期这段代码会同时调用默认构造函数和拷贝构造函数,但实际仅默认构造函数被调用,程序输出为:default constructor called。
核心原因解析
std::shared_ptr<Init> b(a);执行的是智能指针本身的拷贝,它的作用是让新的shared_ptr对象b和a共享同一个Init实例的所有权,并不会创建新的Init对象,自然不会触发任何Init类的构造函数。- 你定义的
Init(std::shared_ptr<Init> z)并不是标准意义上的拷贝构造函数。标准拷贝构造函数的参数必须是当前类的引用(通常是const Init&),而你定义的这个构造函数只有在显式用shared_ptr<Init>去构造新的Init对象时才会被调用,比如Init obj(a);这种场景。
验证与修正
如果想要触发你定义的带shared_ptr参数的构造函数,需要显式创建新的Init实例,修改main函数如下:
int main() { int k = 5; std::shared_ptr<Init> a = std::make_shared<Init>(k); // 显式用shared_ptr构造新的Init对象,再交由shared_ptr托管 std::shared_ptr<Init> b = std::make_shared<Init>(a); return 0; }
运行后会输出:
default constructor called copy constructor called
如果是想触发标准的拷贝构造逻辑,需要先定义标准拷贝构造函数:
Init(const Init& other) { this->x = other.x; cout << "standard copy constructor called" << endl; }
然后通过解引用shared_ptr获取托管对象,再拷贝创建新实例:
std::shared_ptr<Init> b = std::make_shared<Init>(*a);
这样就会调用标准拷贝构造函数,输出对应的日志。
内容的提问来源于stack exchange,提问作者chandu
相关产品推荐
相关产品推荐

