我班的析构者做错了? C ++

时间:2016-04-13 20:13:45

标签: c++ arrays class destructor operator-keyword

我有类Egg,我有预定义的构造函数。这是我的operator =和析构函数的样子:

Egg& Egg::operator=(const Egg& rhs)
{
    if (this == &rhs)
        return *this;

    size = rhs.size;
    name = rhs.name;

    return *this;
}

Egg::~Egg()
{

    size = 0;
    delete[] name;
}

我想做的是一个动态的鸡蛋阵列,每当我创造一个新的鸡蛋时,它就会延伸。我是这样做的:

Egg* eggArr = NULL;
void createEgg()
{
    Egg * temp = eggArr;
    eggArr = new (std::nothrow) Egg[eggsCnt + 1];

    if (!eggArr)
    {
        std::cerr << "No memory!\n";
        return;
    }

    for (size_t i = 0; i < eggsCnt; ++i)
    {
        eggArr[i] = temp[i];
        std::cout << eggArr[i].getName();
    }



    eggArr[basketCnt].setName(eggsCnt, eggArr);


   eggsCnt++;
   delete[] temp; //problematic line
} 

如果我删除delete [] temp,代码可以正常工作,但是存在内存泄漏。 当它停留在程序上时,由于某种原因我的eggArr也被破坏了,然后当我试图接触它的一些成员时,它们是未定义的。我的析构函数,运算符=或其他地方的问题是什么?

1 个答案:

答案 0 :(得分:2)

你有问题:

Egg& Egg::operator=(const Egg& rhs)
{
    name = rhs.name;
    ...
}

Egg::~Egg()
{
    ...
    delete[] name;
}

之后

Egg egg1, egg2;
egg1 = egg2;

nameegg1中的egg2值相同。当他们将要调用它们的析构函数时,它将被删除两次 - 这是一条通往地狱的直接道路。

这是另一个例子,稍微复杂一些:

Egg egg1;
{
    Egg egg2;
    egg2 = egg1;
}         
std::cout << egg1.getName() << "\n";

在第二个示例中,一旦egg2离开了它的范围,name就会被删除 - 并且它与name共享的egg1相同。结果,egg1.getName()将尝试使用已经删除的指针,这也是好的程序员不会参与的事情。

您的复制构造函数和您的代码可能存在同样的问题,解决方案是停止对name执行任何操作并使其成为正确的类型 - 判断为名称std::string似乎合适。