条款33: 避免遮掩继承而来的名称

考虑如下代码:

int x;				// global变量
void someFunc() {
	double x;		// local变量
	std::cin >> x;	// 读一个新值赋予local变量x
}

someFunc函数内使用的x不是为全局变量x,因为ie内层作用域的名称会遮掩外围作用域的名称

当导入继承情况时候,derived class作用域被嵌套在base class作用域内:

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,首先查找local作用域,也就是class Derived覆盖的作用域,还是没有找到任何东西名为mf2,于是再往外围移动,本例为base class,在这里找到了,于是停止查找;如果base内还是没有mf2,查找动作便继续下去,首先找内含Base的那个namespace(s)的作用域,最后往global作用域去;

再次考虑之前例子,这次我们重载mf1和mf3:

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();
	//...
};

以作用域为基础的"名称遮掩规则"没有改变,因此base class内所有的名为mf1和mf3的函数都被derived class内的mf1和mf3函数遮掩掉了:

Derived d;
int x;
d.mf1();	//没问题
d.mf1(x);	//错误,Dervied::mf1遮掩了Base::mf1
d.mf2();	//没问题
d.mf3();	//没问题
d.mf3(x);	//错误,Dervied::mf3遮掩了Base::mf3

如果你想让d.mf1(x)d.mf3(x)合法,可以使用using声明达成目标:

class Derived : public Base {
public:
	//...
	using Base::mf1;
	using Base::mf3;
	//...
};

假如Derived以private形式继承Base,而Derived唯一想继承的mf1是那个无参数版本;using声明形式在这里派不上用场,因为using声明会令继承而来的某个给定名称之所有同名函数在derived class中都不可见;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值