3

What is the difference between the destructor and the DeAllocate function in this code?

I don't get it they look like the same thing to me.They do the exact same thing, why would you ever need a function like DeAllocate? Destructor has the benefit of being called automatically, but DeAllocate doesn't.

#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;
}
Christophe
  • 68,716
  • 7
  • 72
  • 138
Matt
  • 2,232
  • 8
  • 35
  • 64
  • 2
    *Destructor has the benefit of being called automatically, but DeAllocate doesn't.* And that's it. Seriously. Look no further than that. RAII depends on this. And the same concept exists in most languages, even managed ones (think `IDisposable` combined with `using` in C# for instance). This makes our everyday lives way better. – Frédéric Hamidi Nov 05 '16 at 00:23
  • Off topic: Strongly recommend `A = nullptr;` over `A = 0;`. The intent of the first is much more obvious to the casual reader. – user4581301 Nov 05 '16 at 00:30
  • 1
    The `DeAllocate()` method should probably not even exist here. It leaves the object in an invalid state. There should only be a destructor. – user207421 Nov 05 '16 at 00:58

2 Answers2

4

One could indeed have rewritten the destructor:

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

The difference is that:

  • The destructor is invoked at destruction (either automatically for local objects when leaving the scope in which the object was created, or when the object gets deleted for freestore objects). After the object is destroyed, the object no longer exist.

  • When you call DeAllocate(); the memory of the array is freed and the status of the object changes, but all its members and the ARRAY_CLASS object itself still exist.

Christophe
  • 68,716
  • 7
  • 72
  • 138
3

The destructor will happen when the object itself is getting removed.

In the example you posted, you could simply rename that function to something else, say void ARRAY_CLASS::ClearArray() instead of void ARRAY_CLASS::DeAllocate(). All you're doing is deallocating the memory used by A, not destroying the whole object.

rebnat
  • 121
  • 9
  • You don't call the destructor. That happens when you delete an object or it loses scope. – rebnat Nov 05 '16 at 00:23
  • 1
    In the example you posted, if the array was the only data you were worried about clearing, you could just have the destructor call the deallocate function. – rebnat Nov 05 '16 at 00:23