编译时继承 类 中的隐式虚拟与显式虚拟
Implicit virtual vs explicit virtual in inherited classes at compile time
TL;DR 我引用的旧代码不符合 C++。令人惊奇的是,代码曾经有效。您不能在构造函数和析构函数中调用虚方法。
我和一位同行讨论了 C++ 中的 virtual
关键字。在较旧的 ubuntu OS 上,我正在开发一个程序,该程序报告有关调用 "pure virtual methods" 的错误,这本不应该发生
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
通过调试器后,我终于在继承的 classes
上添加了 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 是否有任何暗示继承 class 需要 virtual
的东西。他们说是的,标准中需要 virtual,但大多数时候编译器会自动为继承的 classes 填充 virtual。根据我的理解(并且我相信大多数程序员),当您想通过多态性覆盖该函数时,需要 virtual 。但不清楚您是否也需要标记子 class 函数实现。
我对缺乏关于该主题的资源感到惊讶。那是什么? virtual 在现代 C++ 编译器中隐含吗?标准在哪里描述了它?
覆盖虚函数的函数是虚函数。这不是这里的问题。
问题是在 Base
的析构函数 中调用 DoSomethingElse()
(有或没有多余的 this->
)。当构造函数或析构函数调用虚函数时,它会分派到属于 class 的函数版本,其构造函数或析构函数被调用, 而不是 的版本class 源自 class。所以在析构函数中调用 Base::DoSomethingElse()
,这是对纯虚函数的调用,这就是运行时中止的原因。
TL;DR 我引用的旧代码不符合 C++。令人惊奇的是,代码曾经有效。您不能在构造函数和析构函数中调用虚方法。
我和一位同行讨论了 C++ 中的 virtual
关键字。在较旧的 ubuntu OS 上,我正在开发一个程序,该程序报告有关调用 "pure virtual methods" 的错误,这本不应该发生
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
通过调试器后,我终于在继承的 classes
上添加了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 是否有任何暗示继承 class 需要 virtual
的东西。他们说是的,标准中需要 virtual,但大多数时候编译器会自动为继承的 classes 填充 virtual。根据我的理解(并且我相信大多数程序员),当您想通过多态性覆盖该函数时,需要 virtual 。但不清楚您是否也需要标记子 class 函数实现。
我对缺乏关于该主题的资源感到惊讶。那是什么? virtual 在现代 C++ 编译器中隐含吗?标准在哪里描述了它?
覆盖虚函数的函数是虚函数。这不是这里的问题。
问题是在 Base
的析构函数 中调用 DoSomethingElse()
(有或没有多余的 this->
)。当构造函数或析构函数调用虚函数时,它会分派到属于 class 的函数版本,其构造函数或析构函数被调用, 而不是 的版本class 源自 class。所以在析构函数中调用 Base::DoSomethingElse()
,这是对纯虚函数的调用,这就是运行时中止的原因。