C++中能否用单一指针调用不同类的同名run()函数?
C++多态调用问题解答
代码场景
class A { void func() { //new B //new C //new D //*p points to the instance of one of B,C,D p->run(i); } // some pointer *p }; class B { void run(int i); }; class C: public B { void run(int i); }; class D: public B { void run(int i); };
问题
能否无需关注指针p指向的具体类(例如通过void*类型转换),直接通过p调用对应类的run()实现?
解答
不能用void*直接调用成员函数,因为void*是无类型指针,编译器无法识别它指向的对象类型,找不到对应的成员函数地址,编译阶段就会报错。
但你要实现“不用关心p指向具体类,直接调用对应run()”的需求,根本不需要折腾void*,C++原生的多态机制就是干这个的,只需要改一行代码:把基类B的run()声明为虚函数。
修改后的核心代码:
class B { public: // 必须把run设为public,否则子类重写后外部也调用不了 virtual void run(int i); // 加virtual关键字,标记为虚函数 }; class C: public B { public: void run(int i) override; // 加override显式标注是重写基类虚函数,编译时能检查正确性 }; class D: public B { public: void run(int i) override; };
然后把A类里的指针p声明为B*类型,不管p实际指向B、C还是D的实例,调用p->run(i)时,编译器会自动根据p指向的实际对象类型,调用对应类的run()实现,完全不需要你关心具体是哪个子类。
如果非要硬用void*,那你必须先把void强制转换回对应的类指针(比如B、C*),但这又得知道具体类型,完全违背了“无需关注具体类”的需求,纯粹多此一举。
总结:
- 别用void*解决这个问题,虚函数多态是最直接、最符合C++设计的方案
- 基类加virtual,用基类指针指向子类对象,就能自动实现不同子类的方法调用
内容的提问来源于stack exchange,提问作者Qian2501
相关产品推荐
相关产品推荐

