【问题标题】:Scope of pure virtual functions during derived class destruction - In C++派生类销毁期间纯虚函数的范围 - 在 C++ 中
【发布时间】:2011-03-09 13:09:14
【问题描述】:

在销毁派生类对象期间,我首先点击派生类析构函数,然后是基类析构函数(正如预期的那样)。但我很想知道——派生类的函数在什么时候超出范围(被销毁)。

当控件离开派生类析构函数并进入基类时是否会发生这种情况?还是在我们完成基类析构函数后也会发生这种情况。

谢谢

【问题讨论】:

    标签: c++ oop visual-c++ c++11


    【解决方案1】:

    一旦最派生类的析构函数完成,对象的动态类型可以被认为是下一个派生较少的类型。也就是说,在基析构函数中调用虚方法会发现在那个时间点的最终覆盖器处于基层。 (施工时则相反)

    struct base {
       base() { std::cout << type() << std::endl; }
       virtual ~base() { std::cout << type() << std::endl; }
       virtual std::string type() const {
          return "base";
       }
    };
    struct derived : base {
       virtual std::string type() const {
          return "derived";
       }
    };
    int main() {
       base *p = new derived;
       std::cout << p->type() << std::endl;
       delete p;
    }
    // output:
    // base
    // derived
    // base
    

    【讨论】:

    • 不错的答案。这是否意味着“实际上”你不应该从析构函数中调用虚函数?
    • 谢谢大卫。很抱歉下面的长文本:但是假设,我从基类构造函数中生成了一个线程并在基类析构函数中销毁它。该线程调用派生类中实现的虚拟方法。现在在我销毁基类析构函数中的线程之前,线程触发并调用派生类的虚方法。但是我们已经超越了派生类的析构函数。这个线程还会找到派生类中实现的虚方法的定义吗?还是派生类的虚方法实现超出范围。
    • @xtofl:我不会说“不应该”;行为是明确定义的,除非函数是纯虚拟的。但如果你不小心,它可能会变得有点混乱。
    • @Manav:在这种情况下,您将获得未定义的行为,因为析构函数“更改”了动态类型,而其他线程仍然可以访问它。在派生类的析构函数完成之前,您需要确保线程已经停止(或者至少不会再调用虚函数或访问派生类的成员)。
    • 是的,正如 Mike 提到的,纯虚函数就是这种情况。 Scott Meyers 的另一篇精彩文章:artima.com/cppsource/pure_virtual.html
    【解决方案2】:

    函数不会被破坏。

    然而,一旦派生的析构函数完成,虚拟函数就会在 v-table 中删除它们的条目,因此您不能从基 d'tor 调用派生的虚拟函数。

    【讨论】:

    • 谢谢嘘。这是您提到的关于 v-table 的另一个优点。
    猜你喜欢
    • 1970-01-01
    • 2018-10-14
    • 2018-05-02
    • 2018-01-25
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    相关资源
    最近更新 更多