1.构造函数和析构函数的执行顺序
下图是多虚基类的情况,其中A和B类是类C和类D的虚基类,类E是类C和类D的派生类。
各类定义可以简写如下:
class C:virtual public A , virtual public B class D:virtual public A , virtual public B class E:public C , public D
各类构造函数简写如下:
C( ) : A( ) , B( )
D( ) : A( ) , B( )
E( ) : C( ) , D( ) , A( ) , B( );
在创建E类对象时,按从左到右深度优先遍历算法来调用各个构造函数:A --> B --> C --> D --> E
析构函数的执行顺序与构造函数的执行顺序相反。
2.基类与派生类对象的相互转换
1)赋值转换:可以用派生类对象为基类对象赋值,用派生类对象初始化基类对象的指针。但是,基类不能赋值给派生类,也不能用基类对象初始化派生类的引用。
2)指针转换:可以用派生类对象的地址初始化基类对象,这是因为派生类对象与其基类分量具有相同的地址。但是,不允许基类指针赋值给派生类指针,必须通过强制转换来完成,而且必须保证强制转换后的指针所指内存有效。
/****************main.c**********************/ #include <iostream> using namespace std; class A { private: int x; public: A(int xp=0) { x = xp; } void dispA() { cout<<"Hello,this is A and x: "<<x<<endl; } int GetX() { return x; } }; class B:public A { private: int y; publuc: B(int xp = 1,int yp = 1): A(xp) { y = yp; } void dispB() { cout<<"Hello,this is B and x: "<<Getx()<<", y:"<<y<<endl; } }; int main() { A pt1(1); pt1.dispA(); B pt2(2,3); pt2.dispB(); pt1 = pt2; //派生类对象为基类对象赋值 pt1.dispA(); A& rpt1 = pt2; //派生类对象初始化为基类对象引用 rpt1.dispA(); A* ppt1 = &pt2; //派生类对象地址为基类指针赋值 ppt1->dispA(); ((B*)ppt1)->dispB(); //基类指针向派生类强制转换 return 0; }
输出结果如下所示:
Hello,this is A and x:1 Hello,this is A and x:2, y:3 Hello,this is A and x:2 Hello,this is A and x:2 Hello,this is A and x:2 Hello,this is B and x:2, y:3