在重载=中使用delete在派生类中

时间:2013-02-23 18:58:21

标签: c++

我正在阅读C ++ Primer Plus书的第13章。 它有一个例子,它涉及使用继承与动态内存分配,复制构造函数和重载=运算符。

基类(称为baseDMA)有一个私有指针到char,它在构造函数中使用new

class baseDMA
{
private:
   char * label;

...
};

baseDMA::baseDMA(const char * l)
{
    label = new char[std::strlen(l) + 1];
    std::strcpy(label, l);
    ...
}

现在,在重载=运算符时,我们会删除label pointer,因为我们会将其分配给新值,并指向新位置。如果我们不删除它,那么我们以后将无法这样做,因为指针现在将指向不同的东西,并且此指针指向的旧位置不会被删除,并且现在没有任何指向它(这是作者如何在另一章解释它

这是基类的重载=运算符:

baseDMA & baseDMA::operator=(const baseDMA & rs)
{
   if (this == &rs)
      return *this;
   delete [] label;
   label = new char[std::strlen(rs.label) + 1];
   std::strcpy(label, rs.label);
   return *this;
}

接下来,作者定义了一个名为hasDMA的派生类,该类也使用new作为pointer-to-char,他定义如下:

class hasDMA :public baseDMA
{
private:
    char * style;
    ...
};

hasDMA::hasDMA(const char * s, const char * l)
: baseDMA(l)
{
    style = new char[std::strlen(s) + 1];
    std::strcpy(style, s);
}

现在这个部分让我感到困惑的是,当作者为派生类重载=运算符时,在给它一个新值之前他似乎不是delete [] style,就像他用基类的label做了。这就是作者为派生类执行重载=运算符的方式:

hasDMA & hasDMA::operator=(const hasDMA & hs)
{
    if (this == &hs)
       return *this;
    baseDMA::operator=(hs); // copy base portion
    //no delete [] style
    style = new char[std::strlen(hs.style) + 1];
    std::strcpy(style, hs.style);
    return *this;
} 

在释放style指向的内存的原因是什么,就像我们从基类中释放label指向的内存,然后再为它赋值一样?

提前致谢

1 个答案:

答案 0 :(得分:6)

原因是作者犯了一个错误。这是一个很好的例子,说明你应该如何管理自己的记忆 - 他应该使用std::vector来管理自己的记忆。他没有,因此,他的代码非常错误,而且如果你模仿他,这正是你的代码将要去的方式。

此外,他使用严重过时的自我分配检查不再是一个成语,而且没有复制和交换。

简而言之,获得一本新书。这一切都很糟糕。