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

为何拷贝构造函数未被调用?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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:30:15