类的默认函数

1.C++中的空类默认产生以下四个函数:

  • 默认构造函数:A()
  • 拷贝构造函数:A(const A&)
  • 赋值函数:A&operator = (const A&)
  • 析构函数

struct也可以有构造函数、析构函数、继承等,与class的唯一区别是默认的访问控制权限

 

2.默认构造函数
  • 如果没有显示定义构造函数,则C++编译系统在编译时为该类提供一个默认的构造函数。它仅负责创建对象,而不做任何初始化工作
  • 只要定义了一个构造函数,则C++编译系统不再提供默认构造函数(此时如果通过不匹配的方式创建对象会出现编译错误)eg:

  • 显式定义两种默认构造函数的方法(注意:只能有一个默认构造函数)
    • A(){}
    • A (int y = 0 ) {x = y}

 

3.拷贝构造函数与赋值函数
  • 拷贝构造函数的两种调用方式:
    • A a2(a1);
    • A a3 = a2;
  • 赋值函数不是构造函数
  • 拷贝构造函数的3种调用情况:
    • 一个对象以值传递的方式传入函数体
    • 一个对象以值传递的方式从函数返回
    • 一个对象需要通过另外一个对象进行初始化

例题一

 

例题二
在MFC类库中,CObject类的析构函数是虚拟的,为什么MFC的编写者认为虚拟的析构函数是必要的?
构造如下类:
一般情况下,创建派生类对象时会首先调用基类的构造函数,然后调用派生类的构造函数,而在释放对象时,会先调用派生类的析构函数,再调用基类的析构函数。虚函数主要用于解决多态问题。如:
当释放pBase时会调用pBase的析构函数,当把pBase的析构函数设为virtual的,就会先调用派生类的析构函数,再调用基类的析构函数。
 

例题三

析构函数可以为virtual型,构造函数则不能。那么为什么构造函数不能为虚函数呢?[美国某著名移动通信企业2004面试题]

答案:虚函数采用一种虚调用的办法。虚调用是一种可以在只有部分信息的情况下工作的机制,特别允许我们调用一个只知道接口而不知道其准确对象类型的函数。但是如果要创建一个对象,则必须要知道对象的准确类型,因此构造函数不能为虚。

 

例题四

如果虚函数是非常有效的,我们是否可以把每个函数都声明为虚函数?

答案:不行,这是因为虚函数是有代价的:由于每个虚函数的对象都必须维护一个v表,因此在使用虚函数的时候都会产生一个系统开销。如果仅是一个很小的类,且不想派生其他类,则无需使用虚函数。

 

例题五

分析:
A显然需要,如果不定义拷贝构造函数,可能存在多次删除指针的错误。
B.不自定义拷贝函数会造成两个对象的ID不唯一。
C.使用默认的拷贝构造函数,string子对象和vector子对象的类都是成熟的类,都有合适的赋值操作。
D.显然要定义。类的数据成员为对象不适合使用浅拷贝。
 
答案:C
 
例题六
分析以下代码的编译运行结果:
A:编译错误    B:编译成功,运行时程序崩溃    C编程成功,输出10
分析:经尝试,发现编译错误。但是将拷贝构造函数的参数修改为引用后编译通过。因为如果拷贝构造函数允许值传递,就会在拷贝构造函数中调用拷贝构造函数,会形成永无止境的递归调用导致栈溢出。因此在拷贝构造函数中应该使用引用传递。
posted @ 2015-07-09 21:57  Rosanne  阅读(1301)  评论(0编辑  收藏  举报