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

C++中类无默认构造函数时为何必须用构造函数初始化列表?含性能疑问

关于C++构造函数初始化列表的两个问题解答

嘿,这两个问题都是C++里关于构造函数初始化的经典点,我来给你捋明白:

1. 为什么类没有默认构造函数时必须用构造函数初始化列表?

简单来说:没有默认构造函数的类,没法被"默认创建"——必须显式传参调用它的有参构造。

如果不用初始化列表,而是在构造函数体里给成员赋值,编译器的执行逻辑是这样的:先尝试用默认构造函数创建这个成员对象,然后再在构造函数体里给它赋值。但问题是这个类根本没有默认构造函数,编译器找不到可以调用的默认构造来完成第一步的对象创建,直接就会编译报错。

举个直白的例子:假设你有个类A只有A(int)这个构造函数,如果你在类B里把A当成员,写B() { a = A(5); }——这时候编译器会先试图默认构造a,但A没默认构造,直接就给你报错。只有用初始化列表B() : a(5) {},才能跳过默认构造的步骤,直接调用A的有参构造来初始化a。

2. 基类/成员类无默认构造时必须用初始化列表的原因,以及是否有性能提升?

为什么必须用初始化列表?

C++里对象的初始化顺序是铁律:先初始化基类,再初始化成员对象,最后执行构造函数体。

如果基类A没有默认构造函数,那创建子类B的对象时,必须在B的构造函数初始化阶段就调用A的有参构造——因为基类的初始化要在子类构造函数体执行之前完成,你根本没法在构造函数体里去"补"基类的初始化(这时候编译器已经尝试过默认构造基类,早就报错了)。

成员对象也是同样的道理:成员对象的初始化发生在构造函数体执行之前,所以必须在初始化列表里调用它的有参构造,不然编译器还是会尝试默认构造,直接报错。

有没有性能提升?

必须有!而且对于复杂对象来说提升还挺明显。

如果不用初始化列表,编译器会先默认构造成员/基类对象(假设能默认构造的话),然后再在构造函数体里赋值——这相当于做了两次操作:构造+赋值。而用初始化列表的话,直接一步完成构造和初始化,少了一次赋值的开销。

比如对于那些带动态内存分配的类、或者拷贝/赋值开销很大的类(比如std::string、自定义的大对象),少一次赋值操作能省不少时间和资源。

代码示例

#include <iostream>
using namespace std;
class A {
    int i;
public:
    A(int);
};
A::A(int arg) {
    i = arg;
    cout << "A's Constructor called: Value of i: " << i << endl;
}
// Class B is derived from A
class B : public A {
public:
    // 必须用初始化列表调用A的有参构造,否则编译报错
    B(int val) : A(val) {
        cout << "B's Constructor called" << endl;
    }
};
// Class C contains A as a member
class C {
    A a;
public:
    // 必须用初始化列表初始化成员a,否则编译报错
    C(int val) : a(val) {
        cout << "C's Constructor called" << endl;
    }
};
int main() {
    B b(10);
    C c(20);
    return 0;
}

运行这段代码会输出:

A's Constructor called: Value of i: 10
B's Constructor called
A's Constructor called: Value of i: 20
C's Constructor called

能清楚看到初始化顺序是先基类/成员,再子类/包含类的构造函数体。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:00:09