能否从基类成员函数调用子类重写的静态成员函数?
能否从基类A的成员函数A::foo()中调用子类B重写的静态成员函数B::baz()?
结论:不能直接通过常规调用实现,因为静态成员函数不支持C++的多态机制,编译期就会确定调用的是基类的静态函数。
示例代码验证
给出的测试代码如下:
class A { public: virtual void foo() { bar(); baz(); } virtual void bar() { std::cout << "A::bar()" << std::endl; }; static void baz() { std::cout << "A::baz()" << std::endl; } }; class B : public A { public: void bar() override { std::cout << "B::bar()" << std::endl; }; static void baz() { std::cout << "B::baz()" << std::endl; } };
执行调用代码:
B b; b.foo();
输出结果:
B::bar() A::baz()
可见bar()作为虚函数实现了多态调用,但baz()作为静态函数,始终调用的是基类A的版本。
原因分析
- 静态成员函数是类级别的成员,不属于任何对象实例,也不会被纳入虚函数表,因此不支持运行时多态机制。
- 在A::foo()中直接写
baz(),编译器会将其解析为A::baz(),这个绑定过程在编译阶段就已完成,不会因为调用foo()的对象是B的实例而动态切换到B::baz()。
实现类似效果的方案
如果需要在A::foo()中根据对象实际类型调用对应子类的静态baz(),可以通过虚函数封装静态函数调用的方式实现:
class A { public: virtual void foo() { bar(); call_baz(); } virtual void bar() { std::cout << "A::bar()" << std::endl; }; static void baz() { std::cout << "A::baz()" << std::endl; } // 新增虚函数封装静态调用逻辑 virtual void call_baz() { baz(); } }; class B : public A { public: void bar() override { std::cout << "B::bar()" << std::endl; }; static void baz() { std::cout << "B::baz()" << std::endl; } // 重写虚函数,调用B的静态baz void call_baz() override { baz(); } };
此时执行B b; b.foo();,输出会变为:
B::bar() B::baz()
内容的提问来源于stack exchange,提问作者DrPepperJo
相关产品推荐
相关产品推荐

