构造函数 1.基类构造函数。如果有多个基类,则构造函数的调用顺序是某类在类派生表中出现的顺序,而不是它们在成员初始化表中的顺序。 2.成员类对象构造函数。如果有多个成员类对象则构造函数的调用顺序是对象在类中被声明的顺序,而不是它们出现在成员初始化表中的顺序。 3.派生类构造函数。 析构函数 下面用例子来说说构造函数的的调用顺序: #include "stdafx.h" #include "iostream" using namespace std; class Base { public: }; class Base1:public Base { public: }; class Derive { public: }; class Derive1:public Base1 { private: public: }; int _tmain(int argc, _TCHAR* argv[]) { } 运行结果是: Base::Base() Base1::Base1() Derive::Derive() Derive1::Derive1() Derive1::~Derive1() Derive::~Derive() Base1::~Base1() Base::~Base() 那么根据上面的输出结果,笔者稍微进行一下讲解,构造函数的调用顺序是;首先,如果存在基类,那么先调用基类的构造函数,如果基类的构造函数中仍然存在基类,那么程序会继续进行向上查找,直到找到它最早的基类进行初始化;如上例中类Derive1,继承于类Base与Base1;其次,如果所调用的类中定义的时候存在着对象被声明,那么在基类的构造函数调用完成以后,再调用对象的构造函数,如上例中在类Derive1中声明的对象Derive m_derive;最后,将调用派生类的构造函数,如上例最后调用的是Derive1类的构造函数。 virtual析构函数 下面来说一说为多态基类声明virtual析构函数: 在C++中,构造函数不能声时为虚函数,这是因为编译器在构造对象时,必须知道确切类型,才能正确的生成对象,因此,不允许使用动态束定;其次,在构造函数执行之前,对象并不存在,无法使用指向此此对象的指针来调用构造函数,然而,析构函数是可以声明为虚函数;C++明白指出,当derived class对象经由一个base class指针被删除,而该base class带着一个non-virtual析构函数,其结果未有定义---实际执行时通常发生的是对象的derived成分没被销毁掉。 看下面的例子: class Base { public: }; class Derive:public Base { public: }; int _tmain(int argc, _TCHAR* argv[]) { } 输出的结果是: Base::Base() Derive::Derive() Base::~Base() 从上面的输出结果可以看出,析构函数的调用结果是存在问题的,也就是说析构函数只作了局部销毁工作,这可能形成资源泄漏败坏数据结构等问题;那么解决此问题的方法很简单,给base class一个virtual析构函数; class Base { public: }; class Derive:public Base { public: }; int _tmain(int argc, _TCHAR* argv[]) { } 输出结果是: Base::Base() Derive::Derive() Derive::~Derive() Base::~Base() 可能上面的输出结果正是我们所希望的吧,呵呵!由此还可以看出虚函数还是多态的基础,在C++中没有虚函数就无法实现多态特性;因为不声明为虚函数就不能实现“动态联编”,所以也就不能实现多态啦! |
|
来自: 哈飞扬 > 《特殊函数以及特殊类》