如下类定义中,下列哪些选项声明或者定义是正确的()
#include <stdio.h>
class Base {
public:
virtual int fcn(){printf("Base fcn");}
};
class D1 : public Base {
public:
// using Base::fcn; // 增加,则可以编译通过
int fcn(int){printf("D1 fcn(int)");}
};
class D2 final : public D1 {
public:
int fcn(int){printf("D2 fcn(int)");}
int fcn(){printf("D2 fcn");}
};
int main(int argc, char** argv)
{
D1 d1obj; D2 d2obj;
D1* dp = &d1obj;
dp->fcn(42); //语句1
dp->fcn(); //语句2
dp = &d2obj;
dp->fcn(42); //语句3
dp->fcn(); //语句4
return 0;
}
A:语句1输出:D1 fcn(int) B:语句2输出:Base fcn C:语句3输出:D1 fcn(int) D:语句4输出:D2 fcn
语句2编译不过,D1的fcn(int)不是虚函数,它将隐藏Base的fcn()。 语句4编译不过,虽然D2中有fcn()函数,它覆盖了Base的fcn(),但是该指针类型为D1,仍将隐藏Base的fcn()所覆盖的D2的fcn(),所以并不正确。
编译失败信息:
26?? ?13? ? main.cpp?? ?[Error] no matching function for call to 'D1::fcn()'? ?-----语句2
29?? ?13? ? main.cpp?? ?[Error] no matching function for call to 'D1::fcn()'? ?-----语句4
原因:
奥秘在于,子类重载了父类的同名函数。此时父类的函数确实对子类是不可见的……
这其实不是一个复杂的知识点,只是容易让人稍不留意就遗忘。
解决方法:
一行using就可以搞定!
using Base::fcn; ?// 增加,则可以编译通过?
注意这不是C++11!这是C++11之前就有的using语法。
另外:
C++ 重写,子类和父类的函数名和入参,返回值必须要是一样的,overide
|