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

C++ template结合shared_ptr编译时找不到A默认构造函数解决方法

报错根因

C++的类构造有个硬规则:所有非静态成员变量必须在构造函数执行完毕前完成初始化。如果你没在构造函数的初始化列表里明确写某个成员怎么初始化,编译器会自动调用这个成员类型的无参构造来初始化它,这个逻辑和你外部传了什么参数进来没有任何关系。
对应到你的代码,问题出在两个地方:

  • 你给A类写了一个接收const std::string&参数的构造函数,这种情况下编译器不会再自动给A生成无参的默认构造函数。
  • 类B的构造函数初始化列表里只初始化了field1,剩下两个成员A field2、CLIENT field3(你实例化的是B<A>,所以field3的类型也是A)都没写初始化逻辑,编译器就会尝试调用A的无参构造来初始化这俩成员,找不到自然就报错了。

你在main函数里提前创建的a只是传给B构造函数的实参,只用来初始化你显式指定的field1,和B自己持有的field2、field3完全没关系——这俩是每个B实例独立占有的成员,必须单独初始化,不可能直接复用外部的a对象。另外这个报错和std::make_shared没关系,它只是负责把你传入的a转发给B的构造函数,问题根源在B自己的构造逻辑上。

修复方案

根据你的实际业务需求二选一就行:

  • 方案1:给A补充无参默认构造
    如果你允许A的对象不传入参数直接创建,直接在A的public权限区域加一行声明即可:
    class A 
    {
    private:
        std::string field1;
        std::string field2;
    public :
        A() = default; // 显式指定编译器生成无参构造
        A(std::string const& s1):field1(s1){};
        virtual ~A(){};
    };
    
    注意用这个方案的话,B里的field2和field3会走无参构造,后续你要记得给它们赋值再使用,避免出现值不符合预期、甚至未定义行为的问题——毕竟你原来的muFunc是直接返回field3的。
  • 方案2:在B的构造函数里显式初始化所有成员(推荐)
    不需要改动A的代码,直接在B的初始化列表里把所有成员的初始化逻辑写全即可,示例(初始值可以按你实际业务逻辑调整):
    B(A const&  a1):
      field1(a1),
      field2(a1),
      field3(std::string("init_val"))
    {};
    
    这种写法没有额外的性能开销,也能从根源上避免成员漏初始化的问题,是更规范的写法。

内容的提问来源于stack exchange,提问作者Ioan Le Gué

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:24:28