开发者

Is it ok to call a member function of an object being destroyed inside the destructor of another object?

To be more specific:

class B;
class A
{
    public:
        A(B &b) : _b(b) { }
        ~A() { _b.do_so开发者_StackOverflow中文版mething(); }

    private:
        B &_b;
};

class B
{
    public:
        B() { }

        /** other methods */

        ~B()
        {
            for (std::list<A*>::iterator it = _bees.begin(); it != _bees.end(); ++it) {
                delete *it;
            }
        }
        void do_something();

    private:
         std::list<A*> _bees;
};

Is it ok to do that?


You are referencing b in A::~A () and not _b, which will not compile. Assuming that you meant _b, then answer is - it depends. It depends on a lifetime of the object of class B that is being references by A. If object of class B is destroyed before destructor of A class is called, then it is not OK, otherwise it is OK. In either case this code is not very fool proof, and many will consider re-designing to make it less dangerous.

If there is no strong guarantee that B will still be there when A is destroyed, then you need to do a bit a re-design. You can, for example, store B by value (copy it), or use reference counted or other "smart" pointers.


Yes, assuming _b is still valid (you're using it through a reference). You can call members of _b so long as they do not throw an exception! Throwing exceptions from a destructor is Not Good (tm).


It's safe on language level. However, on design-level this should always make you ask the question "why do I need tasks to be carried out inside a dying object?".

For instance, this can go bad if the destructor is one step of a cleanup sequence which has been initiated by an error, and if your do_something() method fails. Now you have two errors, where one is distrupting the recovery of the other.


For the code you've posted it is OK.

But be careful about function B::do_something nature and effects. This function should not be virtual. It should not throw (as already mentioned) and other effects of this function should not corrupt the process being performed. E.g. consider this:

   ~B()
    {
        for (std::list<A*>::iterator it = _bees.begin(); it != _bees.end(); ++it) {
            delete *it; /* this->do_something() implicitly called here must not
                                 invalidate iterator it */
        }
    }
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜