C++浅析——继承类内存分布和虚析构函数
继承类研究
1、 Code
1.1 Cbase, CTEST为基类,CTest2为其继承类,并重新申明了基类中的同名变量
class CBase { public: int Data; CBase(); ~CBase(); }; class CTEST { //Data: private: int PrivateData1; int PrivateData2; public: int Data; //Method: public: CTEST(); ~CTEST(); void PrintData(); }; class CTest2 : public CBase, public CTEST { public: int Data; CTest2(); ~CTest2(); void PrintData2(); private: int PrivateData1; int PrivateData2; };
1.2 测试代码
分别输出基类和继承类的大小,但在delete对象的时候是delete基类的对象指针
CTest2* poCTest2 = new CTest2; printf("CTest size = %d, CTest2 size = %d ", sizeof(CTEST), sizeof(CTest2)); CTEST* poCTest = poCTest2; delete poCTest;
2、 运行结果
3、 继承类的大小
尽管继承类中重新定义了和基类中同名的成员变量,但他们并不是同一份数据,而是继承类中包含了基类的全部数据,所以继承类的大小是自身大小加上所有父类的大小,通过VS调试跟踪也可以清楚的看到这一点。
4、 如果父类的析构函数不声明为Virtrual的后果
从运行结果上来看,只打印出了Ctest基类的析构函数输出,Cbase基类和继承类的析构函数都未被调用,如果CBase基类或继承类在析构函数中干了其他事情,那就永远不会执行了。同时由于poCTest的指针和poCTest2的指针不是同一个,导致delete的时候不正确(因为new的时候系统记录的是poCTest2的指针和大小,并未记录poCTest的指针)
5、 如果一个类可能会被继承,则一定要将其析构函数申明为虚函数
将父类申明为虚析构函数后,基类的析构函数就动态绑定为继承类的析构函数了,继承类析构时就会调用父类的析构函数,从而使基类全部正确析构。