网站推广 教程北京疫情最新消息
考虑以下代码:
int x;
void someFunc()
{double x;std::cin >> x;
};
读取数据的语句涉的是局部变量x,而不是全局变量x,因为内层作用域的名称会遮掩外围作用域的名称。
考虑以下的类:
class Base
{
private:int x;
public:virtual void mf1() = 0;virtual void mf2();void mf3();...
};
class Derived:public Base
{
public:virtual void mf1();void mf4();...
}
假设derived class内的mf4的实现代码部分像这样:
void Derived::mf4()
{...mf2();...
}
当编译器看到mf2,编译器的做法是查找各作用域,首先查找mf4覆盖的作用域,没找到,然后查找类Derived
覆盖的作用域,还是没找到,于是继续往外找,在base class里面找到了一个mf2的东西,于是停止查找.
这次我们重载mf1,mf3,并添加一个新版的mf3到Derived
中:
class Base
{
private:int x;
public:virtual void mf1() = 0;virtual void mf1(int);virtual void mf2();void mf3();void mf3(double);...
};
class Derived:public Base
{
public:virtual void mf1();void mf3();void mf4();...
}
考虑以下调用:
Derived d;
int x;
...
d.mf1();
d.mf1(x);
d.mf2();
d.mf3();
d.mf3(x);
其中d.mf1(x)
和d.mf3(x)
可能会让你意外,因为它们都是错误的,主要原因在于:Derived::mf1
和 Derived::mf3
遮掩了Base的
解决办法很简单,可以使用using声明式达成目标:
class Base
{
private:int x;
public:virtual void mf1() = 0;virtual void mf1(int);virtual void mf2();void mf3();void mf3(double);...
};
class Derived:public Base
{
public:using Base::mf1;using Basee::mf2;virtual void mf1();void mf3();void mf4();...
}
假设我们仅仅想要继承基类的mf1是那个无参数的版本,这个时候using声明就不管用了,因为using声明会让继承而来的给定名称的所有同名函数在派生类中都可见,这个时候就需要转交函数了:
class Base
{
private:int x;
public:virtual void mf1() = 0;virtual void mf1(int);...
};
class Derived:public Base
{
public:virtual void mf1() //转交函数{Bsee:mf1();}...
}
总结:
1.派生类内的名称会遮掩基类内的名称。
2.为了让被遮掩的名称重见天日,可使用using语句或转交函数.