开发者

C++ unwanted destruction

Can somebody explain why when c finishes construction, the destructor of b (member of c) is called, while d is destructed - as expected - when c's destructor is called ?

#include <iostream>

using namespace std;

class A
{
public:
    int a, b;
};

class B
{
public:
    A* array[10];
    B()
    {
        for(int i = 0 ; i < 10 ; i++)
            array[i] = new A();
    }
    ~B()
    {
        for(int i = 0 ; i < 10 ; i++)
            delete array[i];
    }
};

class C
{
public:
    B b;
    B* d;
    C()
    {
        b = B();
    }
    ~C()
    {
            delete d;
    }
};

int main()
{
    B b = B();
    C c = C();
    cout 开发者_StackOverflow中文版<< "Ashlamish" << endl;
    system("pause");
    return 0;
}


In b = B() you're constucting a new temporarty instance of class B, assigning a copy to b, then the temporary instance is descructed.


Because in the constructor of C, you are creating a temporary B object in the line c = B(); and when the assignment is complete, that temporary object is being destroyed.


I think you want to declare c like this:

C c;

This will construct an object named c which will be destructed on scope exit. On the other hand, what you have;

C c = C();

will construct an anonymous object of type C, copy construct c with it and immediately destruct the anonymous object. c will still be destructed at the end of the scope.


In the constructor of C you have

    b = B();

what this does is:

  • construct temporary object of type B
  • assign this object to b by the use of default assignment operator
  • destroy the temporary object

To fix this use initialization list in the constructor of C like this:

    C() : b()
    { }

or just leave the constructor empty, that way it will use the default constructor.


The line b = B(); in C constructor instantiates a new object of type B, and uses B's copy constructor to copy such object in C::b.

When C constructor returns b doesn't get destroyed, but the B temporary object used to call b's copy constructor is.

You could just remove such instruction in order to avoid instantiation of a B temporary, in this case b will just be constructed using the default constructor.


destructor of temporary B is called (b = B();), not of member b. this line can be removed at all because b is already default constructed in implicit initialization list


You have committed here a cardinal sin - not obeying the rule of 3.

Your B needs a destructor but does not implement copying and assignment.

You then go ahead and compound the error by actually doing an assignment.

You also go on to delete an uninitialised pointer. (It would be fine if d were NULL but there is no reason why it should be).

You also need to implement copy-construction, especially as your compiler may well choose to use it for the above constructs, although it probably won't actually do so.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜