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

为何C++派生类的默认构造函数会被删除?代码示例解析

问题分析:派生类默认构造函数被删除的原因

首先先贴出触发错误的代码:

template<typename T> 
class Foo { 
    T tVar; 
public: 
    Foo(T t) : tVar(t) {} 
}; 

class FooDerived : public Foo<std::string> {}; 

int main() { 
    FooDerived d; // 此处触发编译错误
    return 0; 
}

错误根源:C++构造函数的生成规则与继承逻辑

我们一步步拆解这个问题的本质:

  1. 基类Foo丢失了默认构造函数
    C++编译器的规则是:如果一个类定义了任意用户自定义的构造函数(这里是带参数的Foo(T t)),编译器就不会再自动为这个类生成默认构造函数(即无参的Foo())。所以Foo<std::string>作为Foo的实例化类,是没有默认构造函数的。

  2. 派生类默认构造函数的生成依赖基类
    对于FooDerived这种没有定义任何构造函数的类,编译器本来会自动生成一个默认构造函数。但这个自动生成的构造函数有个硬性要求:必须调用基类的默认构造函数,来完成基类部分的初始化工作。

  3. 无法完成初始化,导致派生类默认构造函数被标记为删除
    因为基类Foo<std::string>没有可用的默认构造函数,编译器找不到合法的基类构造函数来完成派生类对象的初始化流程。这时编译器不仅无法生成有效的默认构造函数,还会把FooDerived的默认构造函数标记为删除的函数(deleted function)。当你在main里尝试创建FooDerived d;时,自然就触发了"无法引用已删除函数"的错误。

为什么添加基类默认构造函数就能解决问题?

当你给基类Foo补充一个默认构造函数(比如Foo() = default;或者手动实现一个无参构造),Foo<std::string>就拥有了合法的默认构造函数。此时编译器可以正常为FooDerived生成默认构造函数:这个自动生成的构造函数会调用基类的默认构造函数,完成基类部分的初始化,而派生类自身没有额外成员需要处理,整个对象就能正常创建了。

补充:另一种可行的解决思路

除了给基类加默认构造函数,你也可以在派生类中自定义构造函数,显式调用基类的带参构造函数,比如:

class FooDerived : public Foo<std::string> {
public:
    FooDerived() : Foo<std::string>("default_value") {}
};

这样也能绕过错误——因为你自己提供的构造函数已经明确指定了如何初始化基类,编译器不需要再尝试生成默认构造函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:25:28