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

版权声明:转载请注明出处,谢谢!!! https://blog.csdn.net/qhdhnbd110/article/details/83895937

1. using

考虑下面程序:

#include <iostream>
using namespace std;
class Based
{
public:
	void Func()
	{
		cout << "Base" << endl;
	}
	int Func(int x){}
};
class Derived : public Based
{
public:
	int Func()
	{
		cout << "Derived" << endl;
	}
};
int main()
{
	Derived D;
	D.Func(3);
	return 0;
}

我们发现该程序是无法通过编译器的,因为编译器查找名称的规则是:

首先查找当前作用域内是否有相同的名称,如果有,无论类型是否匹配都不再进行查找,如果没有再向上一级作用域查找。

        在该例中,语句D.Func(3)会使编译器首先查找当前作用域也就是Derived中有没有名称Func,找到之后虽然函数类型不匹配但是不再向上查找,所以无法调用父类中的相应的重载函数(注意:子类的作用域包含在父类的作用域之中)。

解决方案:在子类中利用using使父类中的内容子类可见:

#include <iostream>
using namespace std;
class Based
{
public:
	void Func()
	{
		cout << "Base" << endl;
	}
	int Func(int x){}
};
class Derived : public Based
{
public:
	using Based::Func;
	int Func()
	{
		cout << "Derived" << endl;
	}
};
int main()
{
	Derived D;
	D.Func(3);
	return 0;
}

这样,我们就可以使用父类中的重载函数了。

2. 转交函数

        在某些情况下,你可能不想继承父类中的所有函数,当然,这不可能发生在public继承中,因为public继承需要满足is-a模型,但是在private继承中确是有意义的。 

我们不能再次使用using,因为using会使父类中所有的同名函数可见,我们需要一个转交函数:

#include <iostream>
using namespace std;
class Based
{
public:
	void Func()
	{
		cout << "Base" << endl;
	}
	int Func(int x){}
};
class Derived : private Based
{
public:
	void Func()//转交函数
	{
		Based::Func();
	}
};

 这样,我们就可以选择部分继承而不是全部继承。

总结:

如果你想全部继承而且还要重载,那么就在子类中使用using,如果你想部分继承,那么就在子类中使用转交函数。

猜你喜欢

转载自blog.csdn.net/qhdhnbd110/article/details/83895937