虚函数和默认参数
Virtual functions and default parameters
假设我有 class A、B 和 C
class A{
public:
virtual void f4(){
cerr<<"A::f4()"<<endl;
}
};
class B: public A{
public:
virtual void f4(int n){
cerr<<"B::f4("<<n<<")"<<endl;
}
};
class C: public B{
public:
virtual void f4(int n = 1){
cerr<<"C::f4("<<n<<")"<<endl;
}
};
如果我有:
C c;
A& rac = c;
rac.f4();
我原以为会调用 c 的 f4 版本,但事实并非如此。有人可以解释吗?
因为 f4 的签名在 A 和 B/C classes 之间不匹配。
这是 A 对 f4 的函数签名:
void A::f4() // no parameters
B和C使用这个函数签名
void B::f4(int n)
如果您要覆盖一个方法,它需要具有相同的 return 类型和相同的参数列表。否则,即使派生 class 中的方法与父 class 中的方法同名,C++ 也不会将其视为覆盖。
FWIW,C::f4
确实覆盖了 B::f4
。您在 class C
上引入的默认参数不会影响虚拟方法覆盖行为。这就是为什么在我的团队中,我们不允许重载具有不同签名的方法并禁止默认参数的确切原因。因为它会导致这样的错误。
这里是C的v-table(上面可用的方法):
void C::f4(); // no parameters, overrides A::f4()
void C::f4(int n); // overrides B::f4()
编译with clang -Wall出现以下警告:
main.cpp:14:22: warning: 'B::f4' hides overloaded virtual function [-Woverloaded-virtual]
virtual void f4(int n){
^
main.cpp:6:22: note: hidden overloaded virtual function 'A::f4' declared here: different number of parameters (0 vs 1)
virtual void f4(){
^
这些警告解释了发生了什么。虚函数只能被具有相同签名的另一个函数覆盖。
B::f4(int)
不会覆盖 A::f4()
因为它们有不同的参数列表。相反,它是一个不同的虚函数。
所以 rac.f4()
只是调用 A::f4()
,它没有被覆盖。
从 C++11 开始,您可以帮助检测这个问题:
virtual void f4(int n) override {
// ^^^^^^^^
如果这个函数实际上没有覆盖基类的东西,编译器会报错。
假设我有 class A、B 和 C
class A{
public:
virtual void f4(){
cerr<<"A::f4()"<<endl;
}
};
class B: public A{
public:
virtual void f4(int n){
cerr<<"B::f4("<<n<<")"<<endl;
}
};
class C: public B{
public:
virtual void f4(int n = 1){
cerr<<"C::f4("<<n<<")"<<endl;
}
};
如果我有:
C c;
A& rac = c;
rac.f4();
我原以为会调用 c 的 f4 版本,但事实并非如此。有人可以解释吗?
因为 f4 的签名在 A 和 B/C classes 之间不匹配。
这是 A 对 f4 的函数签名:
void A::f4() // no parameters
B和C使用这个函数签名
void B::f4(int n)
如果您要覆盖一个方法,它需要具有相同的 return 类型和相同的参数列表。否则,即使派生 class 中的方法与父 class 中的方法同名,C++ 也不会将其视为覆盖。
FWIW,C::f4
确实覆盖了 B::f4
。您在 class C
上引入的默认参数不会影响虚拟方法覆盖行为。这就是为什么在我的团队中,我们不允许重载具有不同签名的方法并禁止默认参数的确切原因。因为它会导致这样的错误。
这里是C的v-table(上面可用的方法):
void C::f4(); // no parameters, overrides A::f4()
void C::f4(int n); // overrides B::f4()
编译with clang -Wall出现以下警告:
main.cpp:14:22: warning: 'B::f4' hides overloaded virtual function [-Woverloaded-virtual]
virtual void f4(int n){
^
main.cpp:6:22: note: hidden overloaded virtual function 'A::f4' declared here: different number of parameters (0 vs 1)
virtual void f4(){
^
这些警告解释了发生了什么。虚函数只能被具有相同签名的另一个函数覆盖。
B::f4(int)
不会覆盖 A::f4()
因为它们有不同的参数列表。相反,它是一个不同的虚函数。
所以 rac.f4()
只是调用 A::f4()
,它没有被覆盖。
从 C++11 开始,您可以帮助检测这个问题:
virtual void f4(int n) override {
// ^^^^^^^^
如果这个函数实际上没有覆盖基类的东西,编译器会报错。