当前位置:嗨网首页>书籍在线阅读

19-第一种情况_派生类不使用new

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

13.7.1 第一种情况:派生类不使用new

假设基类使用了动态内存分配:

// Base Class Using DMA
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,也未包含其他一些不常用的、需要特殊处理的设计特性:

// derived class without DMA
class lacksDMA :public baseDMA
{
private:
    char color[40];
public:
...
};

是否需要为lackDMA类定义显式析构函数、复制构造函数和赋值运算符呢?不需要。

首先,来看是否需要析构函数。如果没有定义析构函数,编译器将定义一个不执行任何操作的默认析构函数。实际上,派生类的默认析构函数总是要进行一些操作:执行自身的代码后调用基类析构函数。因为我们假设lackDMA成员不需要执行任何特殊操作,所以默认析构函数是合适的。

接着来看复制构造函数。第12章介绍过,默认复制构造函数执行成员复制,这对于动态内存分配来说是不合适的,但对于新的lacksDMA成员来说是合适的。因此只需考虑继承的baseDMA对象。要知道,成员复制将根据数据类型采用相应的复制方式,因此,将long复制到long中是通过使用常规赋值完成的;但复制类成员或继承的类组件时,则是使用该类的复制构造函数完成的。所以,lacksDMA类的默认复制构造函数使用显式baseDMA复制构造函数来复制lacksDMA对象的baseDMA部分。因此,默认复制构造函数对于新的lacksDMA成员来说是合适的,同时对于继承的baseDMA对象来说也是合适的。

对于赋值来说,也是如此。类的默认赋值运算符将自动使用基类的赋值运算符来对基类组件进行赋值。因此,默认赋值运算符也是合适的。

派生类对象的这些属性也适用于本身是对象的类成员。例如,第10章介绍过,实现Stock类时,可以使用string对象而不是char数组来存储公司名称。标准string类和本书前面创建的String类一样,也采用动态内存分配。现在,读者知道了为何这不会引发问题。Stock的默认复制构造函数将使用string的复制构造函数来复制对象的company成员;Stock的默认赋值运算符将使用string的赋值运算符给对象的company成员赋值;而Stock的析构函数(默认或其他析构函数)将自动调用string的析构函数。