类成员的重载 覆盖和隐藏或许是许多朋友都没彻底明白的语法,在这里,我们试着通过名字空间的解析来理解派生类中隐藏基类的虚拟重载函数.
先来看一个例子:
#include <iostream.h>
class B
{
private:
int nNumber;
public:
virtual void test() { cout << "B::test()/n"; }
virtual void test(int x) { nNumber = x; // 将传入的参数赋值给私有成员 cout << "B::test(int x)/n"; }
};
class D : public B
{
public:
//test(void) 隐藏 B::test(int)
virtual void test() { cout << "D::test()/n"; }
};
void main(int argc, char* argv[])
{ D d; // 派生类的实例
d.test(); // OK
d.test(17); // 产生编译错误的代码行
}
有两个概念需要理清:
1.重载
2.名字空间从名字空间的角度看,当C++试图解决某个符号名时,它以由近到远的顺序进行搜索,它首先找本地变量,然后是类成员名,接着是基类名,全局变量……。
一旦编译器解析了名字,它便终止解析过程。如果在不同的名字空间范围碰到同一个符号名,那么它便没有了主意。在你的代码中,一旦编译器确定名字"test"出现在类D中,那么它的名字空间就为类D。不论你调用不带参数的test也好,还是调用带一个整型参数的test(17)也好,编译器都是遵循准这个规则来解决名字问题。对于有整型参数的test(int x)函数,一旦编译器确定函数名test生存在类D中,它便终止范围探查,然后查找与参数匹配的函数。由于它没有在类D中找到带整型参数的函数,所以报错。此时编译器认为函数D::test(void)隐藏了函数B::test(int)。
解决方案:
1.重载test(int)class D : public B {public: virtual void test(int x) { B::test(x); } ……};
2.引入"using"class D : public B {public: using B::test; // 改写test virtual void test() { cout << "D::test()/n"; }};
后记:抱歉了,格式很乱.目前还不知道怎么排版~