如果我有一个Base和一个派生类:
class Base {
//...
};
class Derived : public Base {
//...
};
是否可以通过以下方式重载功能?
void DoSomething(Base b) {
cout << "Do Something to Base" << endl;
}
void DoSomething(Derived d) {
cout << "Do Something to Derived" << endl;
}
如果我这样做会发生什么:
int main() {
Derived d = Derived();
DoSomething(d);
}
Derived也是一个Base ..所以调用哪个版本?
答案 0 :(得分:10)
是的,C ++允许您重载基类和派生类的函数。实际上,标准库<algorithm>
函数使用此机制来根据传入的迭代器类型选择正确的算法。
Derived
对象也是Base
,但DoSomething(Derived)
是完全匹配的,因此它是首选。 DoSomething(d)
会致电DoSomething(Derived)
。
但请注意,您无法通过这种方式获得多态行为。也就是说,如果您有一个实际引用Base&
对象的Derived
,它仍然会调用DoSomething(Base)
:也就是说,会调度静态类型。 (实际上,由于您通过值传递,它只将对象的Base
部分复制到参数中。)要获得多态行为,您必须将DoSomething
转换为虚拟成员函数(或让DoSomething(Base& b)
在b
上调用虚拟成员函数。)
答案 1 :(得分:2)
派生函数将被调用并使用,因为它匹配“DoSomething(Derived d)” 签名。
您是否考虑过使用这样的代码:
#include<iostream>
using namespace std;
class Base {
public:
virtual void DoSomething();
};
class Derived : public Base {
public:
void DoSomething() override;
};
void Base:: DoSomething() {
cout << "Do Something to Base" << endl;
}
void Derived :: DoSomething() {
cout << "Do Something to Derived" << endl;
}
int main() {
Base *d = new Derived();
d->DoSomething();
delete d;
return 0;
}
它完成了相同的任务,并允许您利用多态性的优势。