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

using delete in overloaded = in derived class

本文关键字:重载 中的 delete 派生      更新时间:2023-10-16

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

称为 baseDMA 的基类具有在构造函数中使用 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指向的内存一样?

提前致谢

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

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

简而言之,买一本新书。这都是不好的。