default constructor 的构造函数

C++构造函数合成规则
本文介绍了C++中编译器自动合成默认构造函数的四种情况:1) 类内含有带有默认构造函数的成员对象;2) 派生于带有默认构造函数的基类;3) 声明或继承了虚函数;4) 虚继承了基类。通过实例说明了编译器如何合成这些构造函数。
<Insidethe C++ Object Model>里总结了如下四种情况:

1.如果类内部有成员对象,并且成员对象带有默认构造函数,那么编译器有必要为

这个类合成默认构造函数,以初始化这些成员对象。并且成员对象初始化的顺序是按他们在类中声明的顺序。

例:

class BlackBall {
public:
 
   BlackBall(){ cout << "BlackBall()"<< endl; }
};
class RedBall {
public:
    RedBall() {cout << "RedBall()"<< endl; }
};
class WhiteBall {};
class Container {
public:
    WhiteBallwhiteBall;
    BlackBallblackBall;
    RedBallredBall;
};


编译器为Container类合成的默认构造函数可能像下面这个样子:
Container::Container() {
   BlackBall::blackBall();
   RedBall::redBall();
}



2. 如果一个没有任何constructor的类派生自一个带有defaultconstructor基类,那么编译器需要为这个
类合成一个default constructor,在这个defaultconstructor中调用基类的default construct。
<wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px">如果一个类有各种constructor,但其中没有defaultconstructor,那么编译器会扩展每个constructor,<br> 在每个constructor的开头插入调用基类的defaultconstructor的代码。<br><br> 3. 如果类声明或继承了一个虚函数,那么编译器需要为这个类合成一个defaultconstructor<br> (如果已经存在constructor,就会扩展这个构造函数),以初始化编译器安插在这个类中的指向vtable的指针。<br> 例:<br></span><pre code_snippet_id="192971" snippet_file_name="blog_20140218_3_8035496" name="code" class="cpp"><span style="font-size:18px;">class WithVF { public: virtual voidvf() {} }</span></pre> <span style="font-size:18px"><br><br> 编译器合成的default constructor可能像下面这个样子:<br></span><pre code_snippet_id="192971" snippet_file_name="blog_20140218_4_8144180" name="code" class="cpp"><span style="font-size:18px;">WithVF::WithVF() { this-&gt;vptr = ...//address of vtable }</span></pre> <span style="font-size:18px"><br><br><br> 4. 如果一个类虚继承了一个基类,那么编译器需要为这个类合成一个defaultconstructor<br> (如果已经存在constructor,就会扩展这个构造函数),以初始化编译器安插在这个类中的指向VirtualBase Class的指针。</span></wbr></wbr>
### 默认拷贝构造函数的使用指南 在 C++ 中,如果用户没有显式定义拷贝构造函数,编译器会自动生成一个默认拷贝构造函数。该默认拷贝构造函数的行为是按成员进行浅拷贝(shallow copy),即逐个复制对象的成员变量。 #### 默认拷贝构造函数的特点 - **按成员浅拷贝**:默认拷贝构造函数会逐个复制对象的成员变量。对于基本数据类型,这会直接复制值;对于指针类型,则会复制指针地址,而不是指向的内容。 - **自动调用**:在以下几种情况下,编译器会自动调用拷贝构造函数: - 当一个新对象通过已存在的对象初始化时。 - 当对象作为参数传递给函数时(按值传递)。 - 当对象从函数返回时(按值返回)。 #### 示例代码 以下是一个简单的类定义,展示了默认拷贝构造函数的行为: ```cpp #include <iostream> class MyClass { public: int value; MyClass(int v) : value(v) {} // 带参数构造函数 // 显式定义拷贝构造函数(如果未定义,编译器将生成默认版本) MyClass(const MyClass& other) : value(other.value) { std::cout << "Custom copy constructor called" << std::endl; } }; int main() { MyClass obj1(10); MyClass obj2 = obj1; // 调用拷贝构造函数 std::cout << "obj1.value: " << obj1.value << std::endl; std::cout << "obj2.value: " << obj2.value << std::endl; return 0; } ``` 如果未显式定义拷贝构造函数,编译器生成的版本将按成员复制 `value` 的值。 #### 浅拷贝与深拷贝的区别 - **浅拷贝**:默认拷贝构造函数执行的是浅拷贝,对于指针类型的成员,它只复制指针地址,而不是指向的内容。这意味着两个对象的指针成员将指向同一个内存地址,当其中一个对象修改指针指向的内容时,另一个对象也会受到影响。 - **深拷贝**:如果类包含指针或其他资源(如文件句柄、网络连接等),通常需要显式定义拷贝构造函数以执行深拷贝,即复制指针指向的内容,而不是指针本身。 #### 自定义拷贝构造函数的必要性 在以下情况下,应该显式定义拷贝构造函数: - 类包含指针或动态分配的资源。 - 需要确保对象之间的独立性,避免浅拷贝带来的副作用。 - 需要执行额外的初始化逻辑。 #### 编译器自动生成的拷贝构造函数的限制 - **不适用于资源管理类**:如果类负责管理资源(如内存、文件句柄等),默认拷贝构造函数可能导致资源泄漏或双重释放。 - **不适用于需要深拷贝的场景**:对于包含指针的类,默认拷贝构造函数无法保证对象之间的独立性[^2]。 #### 总结 默认拷贝构造函数适用于简单的类,尤其是那些不包含指针或动态分配资源的类。对于复杂的类,特别是涉及资源管理的类,应显式定义拷贝构造函数以确保正确的拷贝行为。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值