代码之家  ›  专栏  ›  技术社区  ›  Dan

编译时继承类中的隐式虚与显式虚

  •  -1
  • Dan  · 技术社区  · 7 年前

    热释光;博士 我引用的旧代码不符合C++。代码真是太神奇了。不能在构造函数和解构器中调用虚方法。

    我和一位同行讨论了 virtual 关键字在C++中。在一个较旧的ubuntu操作系统上,我正在编写一个程序,该程序报告了调用“纯虚拟方法”的错误,而这本不该发生

    class Base {
        virtual ~Base() { this->DoSomethingElse(); }
        virtual bool DoSomething() = 0;
        virtual bool DoSomethingElse() = 0;
    };
    
    class Foo : public Base {
        ~Foo();
        bool DoSomething();
        bool DoSomethingElse();
    };
    
    // Later...
    Base* obj = new Foo();
    obj->DoSomething(); // Pure virtual function called SIGABORT
    delete obj; // Pure virtual function called SIGABORT
    

    经过调试之后,我终于添加了 事实上的 关于继承类

    class Base {
        virtual ~Base() { this->DoSomethingElse(); }
        virtual bool DoSomething() = 0;
        virtual bool DoSomethingElse() = 0;
    };
    
    class Foo : public Base {
        virtual ~Foo();
        virtual bool DoSomething();
        virtual bool DoSomethingElse();
    };
    
    // Later...
    Base* obj = new Foo();
    obj->DoSomething(); // Ok!
    delete obj; // Ok!
    

    事实上的 在告诉我的同龄人之前,在继承的类上是需要的。他们说,是的,标准中需要虚拟类,但是编译器大多数时候会自动为继承的类填充虚拟类。根据我的理解(我相信大多数程序员),当您想通过多态性重写该函数时,需要虚拟化。但不清楚是否也需要标记子类函数实现。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Pete Becker    7 年前

    重写虚函数的函数是虚函数。这不是问题所在。

    问题是需要 DoSomethingElse() (有无冗余) this-> ) 对于 Base . 当一个构造函数或析构函数调用一个虚函数时,它会分派给属于其构造函数或析构函数被调用的类的函数的版本, 从该类派生的类的版本。所以析构函数调用 Base::DoSomethingElse() ,这是对纯虚拟函数的调用,这就是运行时中止的原因。