【问题标题】:What is the difference between a destructor and a funtion that deallocates?析构函数和分配函数有什么区别?
【发布时间】:2023-03-18 13:00:01
【问题描述】:

这段代码中的析构函数和DeAllocate函数有什么区别?

我不明白它们对我来说看起来是一样的。它们做的事情完全相同,你为什么需要像 DeAllocate 这样的函数?析构函数有自动调用的好处,但 DeAllocate 没有。

#include <iostream>
using namespace std;

const int SIZE=5;

class ARRAY_CLASS
{
public:
    ARRAY_CLASS();//default constructor
    ~ARRAY_CLASS(); //destructor
    void Add(int); //mutator
    void Print(); //accessor
    int * Get_Address(); //accessor
    void DeAllocate(); //mutator
private:

    int *A;
    int count;
};

ARRAY_CLASS::ARRAY_CLASS()
{
    cout<<"Default constructor has been called\n";
    A = new int[SIZE];
    count = 0;
}


ARRAY_CLASS::~ARRAY_CLASS()
{
    cout<<"The Destructor has been Called!\n";
    delete [ ] A;
    A=0;
    count = 0;
}

void ARRAY_CLASS::Add(int item)
{
    if (count<SIZE)
        A[count++]=item;
    else
        cout<<"Array Full\n";
}
void ARRAY_CLASS::Print()
{
    for(int i=0; i<count; i++)
        cout<<"A[i] = "<<A[i]<<endl;
}

int * ARRAY_CLASS::Get_Address()
{
    return A;
}

void ARRAY_CLASS::DeAllocate()
{
    delete [ ] A;
    A = 0;
    count = 0;
}

int main()
{

    ARRAY_CLASS B;

    B.Add(1);
    B.Add(2);
    B.Add(3);
    B.Add(4);
    B.Add(5);

    B.Print();

    ARRAY_CLASS A = B;

    cout<<"A holds address location = "<<A.Get_Address()
    <<" and B holds address location "<<B.Get_Address()<<endl;

    B.DeAllocate();
    A.Print();

    return 0;
}

【问题讨论】:

  • 析构函数有被自动调用的好处,但 DeAllocate 没有。 就是这样。严重地。别再看了。 RAII 取决于此。在大多数语言中都存在相同的概念,甚至是托管语言(例如,在 C# 中将 IDisposableusing 结合使用)。这让我们的日常生活变得更加美好。
  • 离题:强烈推荐A = nullptr;,而不是A = 0;。第一个的意图对于普通读者来说更为明显。
  • DeAllocate() 方法可能不应该在这里存在。它使对象处于无效状态。应该只有一个析构函数。

标签: c++ oop destructor object-lifetime


【解决方案1】:

确实可以重写析构函数:

ARRAY_CLASS::~ARRAY_CLASS()
{
    cout<<"The Destructor has been Called!\n";
    DeAllocate();
}

不同的是:

  • 析构函数在销毁时被调用(在离开创建对象的范围时自动调用本地对象,或者当对象被 freestore 对象删除时)。对象被销毁后,对象不再存在。

  • 当你调用DeAllocate(); 时,数组的内存被释放并且对象的状态改变了,但是它的所有成员和ARRAY_CLASS 对象本身仍然存在。

【讨论】:

    【解决方案2】:

    析构函数会在对象本身被移除时发生。

    在您发布的示例中,您可以简单地将该函数重命名为其他名称,例如 void ARRAY_CLASS::ClearArray() 而不是 void ARRAY_CLASS::DeAllocate()。您所做的只是释放 A 使用的内存,而不是破坏整个对象。

    【讨论】:

    • 你不调用析构函数。当您删除一个对象或它失去作用域时,就会发生这种情况。
    • 在您发布的示例中,如果数组是您担心清除的唯一数据,您可以让析构函数调用 deallocate 函数。
    猜你喜欢
    • 2023-03-10
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 2013-05-30
    相关资源
    最近更新 更多