0

This appears similar to where I'm headed as well as this question.

Consider the following

template<typename T>
class A
{

private:

    class B
    {

    private:

        B* link;

    public:

        B();
       ~B();

    };

    B* head;

public:

    A();
   ~A();
};

The above creates the structure below assuming the function to create and link each B is declared and defined

EI6yn6W

If I perform the operation as shown above, then

B* position = head;
position = head->link;
head->link = nullptr;
delete[] head;
head = position;

I understand that calling the inner class destructor will result in the outer class destructor being called. Have I correctly handled garbage collecting the resource x or have I done something undefined?

Mushy
  • 2,535
  • 10
  • 33
  • 54
  • 1
    Why do you think calling the inner class destructor (which you never do in the sample you posted) will result in the outer class destructor being called? It's the other way around, no? – bnaecker Oct 05 '17 at 20:06
  • 1
    "Have I done something undefined?" Yes. Calling `delete[]` on a non-array type is UB. – bnaecker Oct 05 '17 at 20:09
  • I think you are mistaking "inner" class with "base" class. If base class has virtual destructor then derived ("outer") class's destructor will be called when base ("inner") class destructor is called. And there is no " garbage collecting " in C++. – user7860670 Oct 05 '17 at 20:28

1 Answers1

0

In the code provided the inner class will not call the outer class' destructor, nor should it, as the outer class only has a pointer to the inner class as a member.

There is no need for garbage collection if A is created with automatic storage duration (i.e. as a variable without new). It will be destroyed when it goes out of scope. The rule of thumb is that each new should have a matching delete.

To illustrate I've simplified the code, placed the node removal code in a member function and provided a simple example of its use:

struct A
{
    struct B
    {
        B* link;
    };
    B* head;
    void delete_head()
    {
        B* position = head;
        position = head->link;
        //head->link = nullptr; // not needed, it is being deleted anyway
        delete head; // not delete[]! This isn't an array pointer
        head = position;
    }
};

int main()
{
    A a;
    a.head = new A::B; // create head node
    a.head->link = new A::B; // create node
    a.delete_head(); // call A::~B()
    a.delete_head(); // call A::~B()
    // no more nodes in a, but A's destructor is not yet called
} // A::~A() is called here
wally
  • 10,717
  • 5
  • 39
  • 72