无论如何我可以修改这个代码示例
#include <stdlib.h>
#include <iostream>
class Base {
public:
Base() {
if(!m_initialized) {
static_constructor();
m_initialized = true;
}
}
protected:
virtual void static_constructor() {
std::cout << "Base::static_constructor()\n";
}
private:
static bool m_initialized;
};
bool Base::m_initialized = false;
class Derived : public Base {
void static_constructor() {
std::cout << "Derived::static_constructor()\n";
}
};
int main(int argc, char** argv) {
Derived d;
return(EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)
那么Derived::static_constructor()
被调用而不是Base的?我想初始化一堆静态变量,最合乎逻辑的地方是在类中的某个地方.
你永远不应该从构造函数(或析构函数)调用虚函数!结果将不是"预期的"(因此您看到的结果).为什么?因为在Derived构造函数之前调用了基础构造函数(Base).这意味着虚拟函数可能引用的Derived中的本地数据库尚未初始化.此外,甚至可能更重要的是,vtable尚未使用Derived中的函数进行初始化,仅使用Base的成员.因此,虚函数实际上并不是虚拟的 - 它不会直到Base()完成并且Derived()被处理.
此外,这样做会破坏开放/封闭原则,简而言之就是"类应该开放以进行扩展,但是关闭以进行修改".您正在通过更改Base静态初始化来尝试修改其行为而不是扩展它.这在当时看起来似乎是一个好主意,但有可能它会在以后咬你的屁股;)