这里主要说的是继承体系中的作用域
class B{
private:
int x;
public:
virtual void mf1()=0;
virtual void mf2();
void mf3();
...
};
class D:public B
{
public:
virtual void mf1();
void mf4();
...
};
void D::mf4()
{
...
mf2();
...
}
函数mf4调用mf2查找名字的顺序是先在mf4函数内,再到D类作用域内,还是没有就到基类B中查找,还是没有的话就到B的namespace内找,最后到全局作用域。
考虑下面的例子:
class B{
private:
int x;
public:
virtual void mf1()=0;
virtual void mf1(int);
virtual void mf2();
void mf3();
void mf3(double);
...
};
class D:public B
{
public:
virtual void mf1();
void mf3();
void mf4();
...
};
现在B类的名字mf1和mf3被D类的mf1和mf3掩盖了,所以下面的调用是错误的
int x;
D d;
d.mf1(x); //error
d.mf3(x);//error
这里的继承采用了继承重载函数。is-a是public继承的基石,base中的东西在派生类中都适用,现在base的东西在派生类中不可见,违反了public继承的准则。
你可以使用using声明达成目的:
class D:public B
{
public:
using B::mf1;
using B::mf3;
virtual void mf1();
void mf3();
void mf4();
...
};
现在上面的错误就没有了
现在你只想继承B类中的mf1的无参数函数,怎么办呢?using 声明会导致B类所有的名字在D类中可见,所以using声明在这里就不起作用了。这时候可以用private继承,使用一个简单的转交函数来完成:
class B{
public:
virtual void mf1()=0;
virtual void mf1(int);
....
};
class D:private B
{
public:
virtual void mf1() //转交函数,暗自成为inline函数
{
B::mf1();
}
....
};
但是结合template的时候,我们将面临新的问题。这里不给予讨论。