0

Given the code below, why would I get an error about A's destructor being private? Obviously it is private, but I don't understand why initializing B's A object instance in this way would cause the destructor of A to be called.

Apologies for any typos, I'm recreating the code from memory from a non-networked system and don't have a compiler.

class A
{
    public:
        A(int val) : x(val) {}

    private:
        int x;
        ~A() {}
};

class B
{
    public:
        B() : aInstance() {}

    private:
        A aInstance;
};

int main()
{
    B b;
}
John Humphreys
  • 37,047
  • 37
  • 155
  • 255
  • Can't do it for stack-based objects (even indirectly.) There's a good discussion of private destructor usage and restrictions here: http://stackoverflow.com/questions/631783/what-is-the-use-of-having-destructor-as-private – holtavolt Jan 11 '12 at 18:11

6 Answers6

5

Initializing itself doesn't involve using the dtor, but the instance of B is destroyed at the end of main. The B contains an A, so when the B is destroyed,the A must be destroyed as well -- but A's dtor isn't available, so the code to do that can't be generated.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
2

Since B class contains an instance of A class (as private field aInstance), it has to be destroyed when instance of B is destroyed.

That's exactly what happens inside your main. AsB b; is allocated and created on stack, it gets out of scope when function ends and must be destroyed, like every local object in C++.

Xion
  • 22,400
  • 10
  • 55
  • 79
0

At the end of main(), when B goes out of scope, how is B supposed to deallocate the member of type A?

It can't, because you declared the destructor private.

nsanders
  • 12,250
  • 2
  • 40
  • 47
  • It isn't main that has the problem it is B, in which the compiler will automatically create the destructor that needs to delete the A it doesn't have access to the destructor of. – CashCow Jan 11 '12 at 18:12
0

The reason why is that A is a member of B. The type B's default generated constructor must be rule call the destructor for each of it's fields. Hence there is an implicit call to A destructor here to which it doesn't have access and you get the error

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
0

I doubt the destructor for A is being called from within a constructor. The destructor to A is probably being called when the b goes out of scope in main (when the program terminates.)

Tom
  • 18,685
  • 15
  • 71
  • 81
0

It is actually B that needs access to the destructor and not main().

If you make B a friend of A it will work. If you make main() a friend of A it will not compile.

Because the instance of A is declared as "automatic", i.e. it is a class member, its deletion will not happen in the destructor of B but will happen during B's destruction. However this is considered to be in the scope of the access of B as a class.

CashCow
  • 30,981
  • 5
  • 61
  • 92