C++构造函数和拷贝构造函数详解

构造函数、析构函数与赋值函数是每个类最基本的函数。它们太普通以致让人容易麻痹大意,其实这些貌似简单的函数就象没有顶盖的下水道那样危险。

每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。

对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A 产生四个缺省的函数,例如:

A(void); // 缺省的无参数构造函数

A(const A &a); // 缺省的拷贝构造函数

~A(void); // 缺省的析构函数

A & operate =(const A &a); // 缺省的赋值函数

这不禁让人疑惑,既然能自动生成函数,为什么还要程序员编写?原因如下:

<1>如果使用“缺省的无参数构造函数”和“缺省的析构函数”,等于放弃了自主“初始化”和“清除”的机会,C++发明人Stroustrup 的好心好意白费了。

<2>“缺省的拷贝构造函数”和“缺省的赋值函数”均采用“位拷贝”而非“值拷贝”的方式来实现,倘若类中含有指针变量,这两个函数注定将出错。

C++ 默认构造函数 :

1、每个类必须有一个构造函数,否则没法创建对象;

2、若 程序员没有提供任何构造函数,则 C++提供一个默认的构造函数,该默认构造函数是无参构造函数,它仅负责创建对象,不做任何初始化的工作;

3、只要 programer 定义了一个构造函数(不管是无参还是有参构造),C++就不再提供默认的默认构造函数。即如果为类定义了一个带参的构造函数,还想要无参构造函数,就必须自己定义;

4、与变量定义类似,在用默认构造函数创建对象时,如果创建的是全局对象或静态对象,则对象的位模式全为 0,否则,对象值是随机的。

C++默认拷贝构造函数:

1、默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造.

2、拷贝构造函数对类中每一个数据成员执行成员拷贝(memberwise Copy)的动作.

3、如果数据成员为某一个类的实例,那么调用此类的拷贝构造函数.

4、如果数据成员是一个数组,对数组的每一个执行按位拷贝.

5、如果数据成员是一个数量,如int,double,那么调用系统内建的赋值运算符对其进行赋值.

请看下面代码:

  1. #include <iostream>   
  2. #include <string>   
  3. using namespace std;  
  4.   
  5. class Student  
  6. {  
  7. public:  
  8.     Student()  
  9.     {  
  10.         cout << "构造函数1" << endl;  
  11.     }  
  12.     Student(int k)  
  13.     {  
  14.         cout << "构造函数2" << endl;  
  15.         i = k;  
  16.     }  
  17.     Student(Student const &m)  
  18.     {  
  19.         cout << "拷贝构造函数" << endl;  
  20.         i = m.i * (-1);  
  21.     }  
  22.   
  23.     void p()  
  24.     {  
  25.         cout << i << endl;  
  26.     }  
  27.     ~Student()  
  28.     {  
  29.         cout << "析构函数" << endl;  
  30.     }  
  31. protected:  
  32.     int i;  
  33. };  
  34.   
  35. int main(int argc, char **argv)  
  36. {  
  37.     Student s(9818);  
  38.     // 调用构造函数2   
  39.     s.p();  
  40.   
  41.     Student t(s);  
  42.     // 调用拷贝构造函数   
  43.     t.p();  
  44.   
  45.     Student k = s;  
  46.     // 调用拷贝构造函数   
  47.     k.p();  
  48.   
  49.     Student *p = new Student(s);  
  50.     // 调用拷贝构造函数   
  51.     p->p();  
  52.   
  53.     Student m;  
  54.     // 调用构造函数1   
  55.     m = s;// 赋值运算   
  56.     m.p();  
  57.   
  58.     return 0;  
  59. }  

运行结果:

  1. 构造函数2  
  2. 9818  
  3. 拷贝构造函数  
  4. -9818  
  5. 拷贝构造函数  
  6. -9818  
  7. 拷贝构造函数  
  8. -9818  
  9. 构造函数1  
  10. 9818  
  11. 析构函数  
  12. 析构函数  
  13. 析构函数  
  14. 析构函数  

相关推荐