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

如何在派生类中保留默认构造函数(无需显式添加Derived() = default;)

问题分析与解决方案

咱们先搞清楚为啥你的代码会编译失败:

当你在派生类Derived里声明了任何非模板构造函数(比如你写的explicit Derived(int) {}),C++编译器就不会自动为这个派生类生成默认构造函数了。而且根据标准规则,此时基类的默认构造函数也没法通过using Base::Base;继承到派生类中——因为只要派生类有自己的非模板构造函数,继承构造函数的逻辑就会跳过基类的默认构造函数。这就导致main里的Derived d;找不到可用的无参构造函数,直接报错。

那怎么在不写Derived() = default;的前提下解决这个问题呢?关键是要避免声明非模板构造函数,同时保留接受int参数的构造能力。这里有个实用的技巧:

用模板构造函数替代非模板构造函数

把你原来的explicit Derived(int) {}改成带类型约束的模板构造函数,这样既可以确保只接受int类型的参数,又不会阻止编译器自动生成默认构造函数。修改后的代码如下:

#include <type_traits>

struct Base { Base() = default; };

struct Derived : Base {
    using Base::Base;
    
    // 模板构造函数+类型约束,仅接受int参数
    template<typename T>
    explicit Derived(T) requires std::is_same_v<T, int> {
        // 这里可以写原来Derived(int)里的逻辑
    }
};

int main() {
    Derived d; // 现在编译正常了!
    Derived d2(1); // 依然可以正常初始化int参数的对象
    // Derived d3(3.14); // 会编译错误,符合我们只接受int的预期
}

为什么这个方法有效?

C++标准里规定:只有用户声明的非模板构造函数才会阻止编译器生成默认构造函数。模板构造函数不属于这个范畴,所以编译器会自动为Derived生成默认构造函数,这个生成的构造函数会自动调用基类Base的默认构造函数,完美满足你的需求。

备选方案(局限性较大)

如果你不需要在Derived(int)里写复杂逻辑,也可以把这个构造函数移到一个单独的基类中,让Derived多重继承:

struct Base { Base() = default; };
struct IntHolder { explicit IntHolder(int) {} };

struct Derived : Base, IntHolder {
    using Base::Base;
    using IntHolder::IntHolder;
};

不过这个方法有个明显的局限:IntHolder必须有默认构造函数,否则编译器生成的Derived默认构造函数会因为无法初始化IntHolder而报错。所以相比之下,模板构造函数的方案更灵活通用。

内容的提问来源于stack exchange,提问作者c.bear

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:18:55