为何重写fun()方法后Derived类仍为抽象类,且调用Base::fun(int&)时提示无匹配函数?
嘿,我来帮你理清这两个编译错误的根源,再给你对应的修复方案:
第一个错误:Derived类被判定为抽象类
这是因为你没有正确重写Base类的纯虚函数:
- Base类里的纯虚函数是
virtual int fun() = 0;(无参数),而你在Derived类里定义的是int fun(int x)(带一个int参数)。这不是重写(override),而是函数重载(overload)——两者的函数签名(参数列表)完全不一样。 - 既然Base的纯虚函数
fun()在Derived里没有被实现,Derived就会被编译器判定为抽象类,自然不能用new Derived(a)来实例化对象。
第二个错误:调用
t->fun(b)时找不到匹配的函数 t是Base*类型的指针,编译器会严格按照Base类的接口来查找函数。Base类里的fun()是无参的,但你调用时传了参数b,编译器找不到Base::fun(int&)这个函数,所以报错。
修复方案
根据你的设计意图,有两种修复方式:
方式1:你原本就想让fun接收一个参数
如果你的设计是fun需要带int参数,那先修改Base类的纯虚函数签名,让Derived正确重写它:
#include <iostream> using namespace std; class Base { protected: int s; public: Base(int i = 0) : s(i) {} virtual ~Base() {} // 修改纯虚函数签名,添加参数 virtual int fun(int x) = 0; }; class Derived: public Base { public: Derived(int i) : Base(i) {} ~Derived() { cout << --s << " "; } // 正确重写Base的fun函数,参数签名完全一致 // 建议加上override关键字,编译器会帮你检查是否真的重写了基类函数 int fun(int x) override { return s * x; } }; class Wrapper { public: void fun(int a, int b) { Base *t = new Derived(a); int i = t->fun(b); // 现在函数调用匹配了 cout << i << " "; delete t; } }; int main() { int i, j; cin >> i >> j; Wrapper w; w.fun(i, j); return 0; }
方式2:Base的fun()无参,Derived额外实现带参的重载版本
如果你的设计是Base保留无参的fun(),Derived同时有一个带参的重载版本,那需要先在Derived里重写无参的fun(),再显式转换指针类型来调用带参的版本:
#include <iostream> using namespace std; class Base { protected: int s; public: Base(int i = 0) : s(i) {} virtual ~Base() {} virtual int fun() = 0; }; class Derived: public Base { public: Derived(int i) : Base(i) {} ~Derived() { cout << --s << " "; } // 先正确重写Base的无参fun() int fun() override { return s; } // 再实现带参的重载版本 int fun(int x) { return s * x; } }; class Wrapper { public: void fun(int a, int b) { Base *t = new Derived(a); // 基类指针看不到派生类的重载函数,需要显式转换类型 int i = static_cast<Derived*>(t)->fun(b); cout << i << " "; delete t; } }; int main() { int i, j; cin >> i >> j; Wrapper w; w.fun(i, j); return 0; }
内容的提问来源于stack exchange,提问作者Dev Mukherjee
相关产品推荐
相关产品推荐

