1. 派生类构造函数解析
1.1 构造函数的调用机制
在C++继承体系中,派生类对象的构造过程遵循严格的顺序规则。当创建派生类对象时,构造函数的执行顺序如下:
- 基类构造函数(按继承顺序)
- 成员对象的构造函数(按声明顺序)
- 派生类自身的构造函数体
cpp复制class Base {
public:
Base() { cout << "Base constructor" << endl; }
};
class Derived : public Base {
public:
Derived() { cout << "Derived constructor" << endl; }
};
// 输出顺序:
// Base constructor
// Derived constructor
重要提示:如果基类没有默认构造函数,派生类必须在初始化列表中显式调用基类的某个特定构造函数,否则会导致编译错误。
1.2 初始化列表的规范写法
正确的初始化列表写法需要考虑以下要点:
- 基类构造必须放在初始化列表的最前面
- 成员变量初始化顺序应与声明顺序一致(编译器实际按声明顺序初始化)
- 对于const成员和引用成员,必须在初始化列表中初始化
cpp复制class Student : public Person {
public:
// 推荐写法
Student(const string& name, int id, int age)
: Person(name), // 基类构造
studentId(id), // 成员初始化
age(age) // 保持声明顺序
{
// 构造函数体
}
private:
const int studentId;
int age;
};
1.3 构造失败处理
当基类或成员对象构造失败时(抛出异常),需要注意:
- 已经构造完成的基类和成员会被自动析构
- 派生类构造函数体不会被执行
- 不会调用派生类的析构函数
cpp复制class Resource {
public:
Resource() {
throw runtime_error("Allocation failed");
}
};
class MyClass : public Base {
Resource res;
public:
MyClass() : Base(), res() {
// 如果Resource构造抛出异常,这里不会执行
}
~MyClass() {
// 如果构造函数未完成,这里不会被调用
}
};
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 派生类拷贝构造深度剖析
2.1 拷贝构造的隐式生成规则
编译器自动生成的拷贝构造函数会:
- 对基类部分调用基类的拷贝构造函数
- 对派生类新增成员执行逐成员拷贝(浅拷贝)
cpp复制class Base {
public:
Base(const Base&) { cout << "Base copy" << endl; }
};
class Derived : public Base {
int* data;
public:
// 隐式生成的拷贝构造函数等价于:
// Derived(const Derived& d) : Base(d), data(d.data) {}
};
// 注意:当有指针成员时,这种浅拷贝可能导致问题
2.2 显式实现拷贝构造的要点
当需要自定义拷贝构造时,必须:
- 显式调用基类拷贝构造
- 正确处理派生类新增成员
- 考虑深拷贝需求
cpp复制class String : public Object {
char
