【问题标题】:Calling virtual function from destructor of an inner class从内部类的析构函数调用虚函数
【发布时间】:2018-02-08 01:44:38
【问题描述】:

我有一个看起来像这样的设置

class A
{
    virtual void doSomething() = 0;
    extern "C" A* getSingleton(); 

    class B {
        B() { getSingleton()->doSomething(); }
        ~B() { getSingleton()->doSomething(); }
    };
};

class C : public A
{
    static A a;
    extern "C" A* getSingleton() { return &C::a; }
    void doSomething() { //things }
    // also has a container of Bs that will be added to and removed from regularly
}

在析构函数期间会因 '__cxa_pure_virtual' 而崩溃,但不会在构造函数中崩溃。 C::a 在另一个文件中正确定义,为简洁起见

我读过从 ctors/dtors 调用虚函数通常是一个坏主意,但是在这种情况下,它会使 B 的使用更好,所以我有兴趣让它安全地工作。谁能解释为什么 B 的 ctor 设法做这个狡猾的动作,但 dtor 却不能,然后我该如何正确地重做这个?

【问题讨论】:

  • 您误解了您阅读的内容。在 A 的 c'tor/d'tor 内部调用类 A 的虚函数本身就是问题(直接或间接)。由于B 是一个完全独立的类(它只是在A 内部定义),因此在其构造函数中调用A 的虚函数没有内在问题。
  • VTC:缺少C::a 和 B 对象的定义,这对于确定执行顺序至关重要。我们无法解释不可见的代码。
  • 有一些行之有效的实现单例的方法。这不是其中的一个。使用您选择的搜索引擎找到一个。
  • 这段代码想要完成什么?
  • 你如何声明一个抽象类的实例?还是有更多代码没有显示?

标签: c++ destructor virtual-functions pure-virtual


【解决方案1】:

问题在于执行顺序。

在 C++ 中,对象是从上到下创建的。 什么意思?

当你有 X 和 Y 类时。 Y 类继承自 X。

X = “父亲” Y = “儿子”

当你实例化一个 Y 类型的对象,并在构造函数和析构函数上打上一些字,你会看到首先调用了 X 的构造函数,然后调用了类 Y 的构造函数。

破坏(当然)是反向的。 首先是Y的析构函数,然后是X类的析构函数。

知道了这一点,然后我们来看看您遇到的 OO 问题: 在 X 类(父类)的析构函数中调用 virtual pure 方法。 当X类的析构函数被执行时,Y(子)object不存在了。

那么:X 对象如何找到应该在继承的类/对象中实现的虚拟纯方法?

【讨论】:

  • 如果在 X 的析构函数中调用纯虚方法,您所说的将是正确的,但在 OP 的示例中并非如此。该方法在 Z 的析构函数中被调用,它与 X 或 Y 没有任何关系,除了它嵌套在 X 内部但实际上与 X 的生命周期无关。
猜你喜欢
  • 2021-05-18
  • 2020-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
  • 1970-01-01
  • 2012-01-27
相关资源
最近更新 更多