C++构造函数与析构函数知多少


众所周知,几乎所有的面向对象的编程语言都保护构造函数与析构函数,好学者就要举手了,啥情况啊,Java里面不就没有析构函数嘛。好吧,你问倒我了,不过可以认为Java的垃圾自动回收机制实现了对象析构的功能。管他呢,还是看C++的构造函数和析构函数吧。

构造函数

    对于C++的构造函数,暂且将其分为以下几类:

1. 默认构造函数

2. 隐士转换构造函数

3. 拷贝构造函数

4. 其它构造函数

    1. 默认构造函数表示没有任何参数的构造函数,当自定义任何构造函数以后,将不再自动创建默认构造函数,当然,默认构造函数啥也不干,程序员关心系数顿时大跌。关于默认构造函数还需要关心的一个问题是,当本类继承于另一个类(即父类),父类没有默认构造函数时,本类将自动没有构造函数,并且还必须定义至少能够支持父类初始化的构造函数。

    2. 隐士转换构造函数时什么呢?它是这样一类构造函数,这类构造函数仅含有一个参数。由于C++规定,为只含有一个参数的构造函数自动定义一种隐士转换,将构造函数的参数对应数据类型的对象转换为类对象。如下面例子所示:

  1. class String {  
  2.      String(const char *s);  
  3. };  
  4.   
  5. String s = "hello friends";  

其中字符串“hello friends”通过隐士转换构造函数转换为了String类对象s。这里不得不提一个关键字explicit,比较悲剧的是学了好几年C++后才知道这么一个关键字,这也充分体现了一本好书的重要性。下面来看看explicit的用法,再解释。

  1. class String {  
  2.     explicit String(const char *s);  
  3. };  
  4.   
  5. String s = "hello friends"//编译不通过   
  6.   
  7. String s("hello friends");  //编译通过  

explicit仅用于构造函数,且仅用于隐士转换构造函数,其目的是禁止隐士构造函数功能。如上代码所示,当为构造函数添加explicit关键字后,String s = "hello friends"; 编译不通过。当然,此时构造函数本身还是能够正常工作的。

3. 拷贝构造函数,就是用来复制对象的一种特殊的构造函数。通过它,可以使用一个已经创建好的对象(由拷贝构造函数的参数指定)去初始化一个正准备创建的同类对象。

  1. class 类名  
  2. {  
  3. public:  
  4.     类名(类名 &对象名);  
  5. }; 

如上述代码所述,拷贝构造函数只能有一个参数,并且必须是同类对象的引用。每个类都应该有一个拷贝构造函数,如果用户没有指定,将使用默认的拷贝构造函数。默认拷贝构造函数执行对象的全部内容复制,但有时需要有选择、有变化地复制。这种情况就需要显示定义拷贝构造函数,并实现为感兴趣部分的复制或者为新对象添加某些属性值。

拷贝构造函数最常见的使用方式是在类中含有指针类型属性时,因为默认的拷贝函数是按指拷贝的,即所谓的浅拷贝。这时需要显示定义拷贝构造函数,并显示地将指针从新分配内存并copy以前指向的值到新分配的内存中。

4. 其它构造函数,没什么特别的,就是前面1,2,3未包含的构造函数均属于该类。

  • 1
  • 2
  • 3
  • 下一页

相关内容