可以在另一个对象的析构函数中调用对象的成员函数吗?

时间:2011-06-13 13:46:03

标签: c++ destructor

更具体一点:

class B;
class A
{
    public:
        A(B &b) : _b(b) { }
        ~A() { _b.do_something(); }

    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;
};

这样做可以吗?

4 个答案:

答案 0 :(得分:2)

您引用b中的A::~A ()而不是_b,这将无法编译。假设你的意思是_b,那么回答是 - 这取决于。它取决于B引用的类A对象的生命周期。如果在调用B类的析构函数之前销毁了类A的对象,那么它就不行了,否则就可以了。在任何一种情况下,这个代码都不是非常简单的证据,许多人会考虑重新设计以降低其危险性。

如果没有强有力的保证BA被销毁时仍然存在,那么你需要做一些重新设计。例如,您可以按值存储B(复制它),或使用引用计数或其他“智能”指针。

答案 1 :(得分:2)

是的,假设_b仍然有效(您通过引用使用它)。您可以致电_b 的成员,只要他们不会抛出异常!从析构函数中抛出异常是不好的(tm)。

答案 2 :(得分:1)

语言水平安全。但是,在设计层面,这应该总是让你问“为什么我需要在垂死的物体内进行任务?”。

例如,如果析构函数是由错误启动的清理序列的一个步骤,并且do_something()方法失败,那么这可能会变坏。现在你有两个错误,一个是破坏另一个的恢复。

答案 3 :(得分:1)

对于您发布的代码,可以。

但要注意功能B::do_something的性质和效果。此功能不应该是虚拟的。它不应该抛出(如前所述),此函数的其他效果不应该破坏正在执行的进程。例如。考虑一下:

   ~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 */
        }
    }