基类的构造函数、析构函数、赋值函数都不能被派生类继承。如果类之间存在继承关系,在编写上述基本函数应注意以下事项:
(1)派生类的构造函数应在其初始化列表里显式地调用基类的构造函数(除非基类的构造函数不可访问);
(2)如果基类是多态,那么必须把基类的析构函数定义为虚函数,这样就可以像其他虚函数一样实现动态绑定;否则有可能造成内存泄漏,示例如下:
#include<iostream.h>
class Base
{
public:
virtual ~Base() { cout <<"Base::~Base()"<<endl; }
//...
};
class Derived : public Base
{
public:
virtual ~Derived()
{
}delete p_test;
cout<<“Derived::~Derived()"<<endl;
private:
};char *p_test;
void main(void)
{
}Base *pB = new Derived; //upcast
delete pB;
输出结果为:Derived::~Derived() Base::~Base()
如果析构函数不是虚函数,那么输出结果将为:Base::~Base
就是说,如果基类的析构函数不是虚函数,派生类对象拥有的内存单元就不会释放,因此造成内存泄漏。
(3)在编写派生类赋值函数时,注意不要忘记对基类的数据成员重新赋值,这可通过调用基类的赋值函数来实现,示例如下:
class Base
{
public:
private://...
Base& operator = (const Base& other); //Base的拷贝赋值函数
};int m_i, m_j, m_k;
class Derived : public Base
{
public:
private://...
Derived& operator=(const Derived& other); //Derived的拷贝赋值函数
int m_x, m_y, m_z;
};
Derived& Derived::operator=(const Derived& other)
{
//(1)检查自赋值
if(this != &other)
{
//(2)对基类的数据成员重新赋值
}Base::operator=(other); //因为不能直接操作基类的私有数据成员
//(3)对派生类的数据成员赋值
m_x = other.m_x;
m_y = other.m_y;
m_z = other.m_z;
//(4)返回对象的引用
return *this;
}
提示:要想更好的了解构造函数、析构函数和赋值函数,还需要阅读文献[Cline]、[Meyers]和[Murry]。