第一种情况: 派生类不使用new
假设基类使用了动态内存分配, 并且重新定义复制和赋值运算符:
class BaseDMA
{
private:
char * label;
int rating;
public:
BaseDMA(const char * l = "null", int r = 0);
// 复制构造函数
BaseDMA(const BaseDMA & rs);
virtual ~BaseDMA();
// 赋值构造函数
BaseDMA & operator=(const BaseDMA & rs);
...
};
声明中包含了构造函数使用new时需要的特殊方法: 析构函数, 复制构造函数和重载赋值运算符.
现在从BaseDMA派生除了LackDMA类, 而后者不使用new, 也未包含其他一些不常用的, 需要特殊处理的设计特性:
class LackDMA : public BaseDMA
{
private:
char color[40];
public:
...
};
这种情况不需要为LackDMA类定义显示析构函数, 复制构造函数和重载赋值运算符
因为: 调用这几个方法的时候会自动调用基类的对应的方法, 而基类的对应的方法进行了相关的操作, 而子类又没有自己的new内存的分配, 所以不需要.
第二种情况:派生类使用new
class HasDMA::public BaseDMA
{
private:
// 在构造函数中使用new分配内存
char * style;
public:
...
};
在这种情况下必须为派生类定义显示析构函数, 复制构造函数和赋值运算符.
下面分别对这几种写法做详细讲解:
1.析构函数
派生类析构函数自动调用基类的析构函数, 故其自身的职责是对派生类构造函数执行的工作进行清理. 因此HasDMA析构函数必须释放指针style管理的内存, 并依赖于BasDMA的析构函数来释放指针label管理的内存:
BaseDMA::~BaseDMA()
{
delete[] label;
}
HasDMA::~HasDMA()
{
delete[] style;
}
2.复制构造函数
BaseDMA的复制构造函数遵循用于char数组的常规模式:
BaseDMA::BaseDMA(const BaseDMA & rs)
{
label = new char[std::strlen(rs.label) + 1];
std::strcpy(label,