TL; DR 我正在引用的旧代码与C ++不兼容。该代码曾经工作过真是太神奇了。您不能在构造函数和反构造函数中调用虚拟方法。
一个同龄人和我讨论了C ++中的virtual
关键字。在较旧的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
逐步调试之后,我终于在继承的类上添加了virtual
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!
在告诉同辈之前,我仔细检查了google是否发现可能建议在继承的类上使用virtual
的所有内容。他们说是的,标准中需要虚拟的,但是编译器大多数时候会自动为继承的类填充虚拟。根据我的理解(我相信大多数程序员),当您想通过多态性覆盖该功能时,就需要虚拟的。但是尚不清楚您是否也需要标记子类函数的实现。
我对该主题缺乏资源感到惊讶。那是什么在现代C ++编译器中是否隐含虚拟的?该标准在何处进行了描述?
答案 0 :(得分:2)
覆盖虚拟功能的功能是虚拟的。这不是这里的问题。
问题是在析构函数中为DoSomethingElse()
调用this->
(有或没有冗余Base
)。当构造函数或析构函数调用虚拟函数时,它会分派给属于正在调用其构造函数或析构函数的类的函数版本,而不不分配给从该类派生的类的版本。因此,析构函数中的该调用将调用Base::DoSomethingElse()
,这是对纯虚函数的调用,这就是运行时中止的原因。