Why doesn't the C++ default destructor destroy

2019-03-12 06:12发布

The C++ specification says the default destructor deletes all non-static members. Nevertheless, I can't manage to achieve that.

I have this:

class N {
public:
    ~N() {
        std::cout << "Destroying object of type N";
    }
};

class M {
public:
    M() {
        n = new N;
    }
//  ~M() { //this should happen by default
//      delete n;
//  }
private:
    N* n;
};

Then this should print the given message, but it doesn't:

M* m = new M();
delete m; //this should invoke the default destructor

13条回答
\"骚年 ilove
2楼-- · 2019-03-12 06:38

The default destructor is destroying the pointer. If you want to delete the N with M's default destructor, use a smart pointer. Change N * n; to auto_ptr<N> n; and n will be destroyed.

Edit: As pointed out in comments, auto_ptr<> is not the best smart pointer for all uses, but it looks like what's called for here. It specifically represents ownership: the N in an M is there for the duration of the M and no longer. Copying or assigning an auto_ptr<> represents a change in ownership, which is usually not what you want. If you wanted to pass a pointer from M, you should pass a N * gotten from n.get().

A more general solution would be boost::shared_ptr<>, which will be in the C++0x standard. That can be used pretty much wherever a raw pointer would be used. It's not the most efficient construct, and has problems with circular references, but it's generally a safe construct.

Another edit: To answer the question in another comment, the standard behavior of the default destructor is to destroy all data members and base classes. However, deleting a raw pointer simply removes the pointer, not what it points to. After all, the implementation can't know if that's the only pointer, or the important one, or anything like that. The idea behind smart pointers is that deleting a smart pointer will at least lead to the deletion of what it points to, which is usually the desired behavior.

查看更多
欢心
3楼-- · 2019-03-12 06:45

What makes you think the object n points to should be deleted by default? The default destructor destroys the pointer, not what it's pointing to.

Edit: I'll see if I can make this a little more clear.

If you had a local pointer, and it went out of scope, would you expect the object it points to to be destroyed?

{
    Thing* t = new Thing;

    // do some stuff here

    // no "delete t;"
}

The t pointer is cleaned up, but the Thing it points to is not. This is a leak. Essentially the same thing is happening in your class.

查看更多
对你真心纯属浪费
4楼-- · 2019-03-12 06:45

Try avoiding using pointers. They are last resort elements.

class N {
public:
    ~N() {
        std::cout << "Destroying object of type N";
    }
};

class M {
public:
    M() {
       // n = new N; no need, default constructor by default
    }
//  ~M() { //this should happen by default
//      delete n;
//  }
private:
    N n; // No pointer here
};

Then use it this way

main(int, char**)
{
    M m;
}

This will display Destroying object of type N

查看更多
等我变得足够好
5楼-- · 2019-03-12 06:49

Since you are using new to create instance, it won't delete by default.

查看更多
闹够了就滚
6楼-- · 2019-03-12 06:51

Imagine something like this:

class M {
public:
    M() { }
//  ~M() {        // If this happens by default
//      delete n; // then this will delete an arbitrary pointer!
//  }
private:
    N* n;
};

You're on your own with pointers in C++. No one will automatically delete them for you.

The default destructor will indeed destroy all member objects. But the member object in this case is a pointer itself, not the thing it points to. This might have confused you.

However, if instead of a simple built-in pointer, you will use a smart pointer, the destruction of such a "pointer" (which is actually a class) might trigger the destruction of the object pointed to.

查看更多
倾城 Initia
7楼-- · 2019-03-12 06:51

M destructor should have 'delete n'.

查看更多
登录 后发表回答