我们先看一个例子:
class Base
{
public:
void print(string) const ;
// ...
};
class Derived1 : public Base
{
public:
void print(int) const ;
// ...
};
class Derived2 : public Base
{
public:
void print(double) const ;
// ...
};
class MI : public Derived1,public Derived2
{
public:
void print(complex<double>) const ;
};
上面的例子,我们定义了类层次结构。当执行下面的语句时将会产生编译错误:
MI mi ;
string dancer("Nijingsky") ;
mi.print(dancer) ;
为什么会出现编译错误呢?问题是对于类MI的对象而言,可见的print函数是:
void print(complex<double>) const ;
因此,编译器无法将一个string对象转换成complex<double>对象。为什么可见的print函数只有这一个呢?这是因为print函数并没有被重载。因为“重载函数解析程序”有一个限制:重载的函数必须是位于同一个scope(区域)中。在这里就是,重载的函数必须位于同一个class中。所以,在类MI中,可见的print函数只有一个。因为其他的print函数并没有与其在同一个class中。
如何解决这个问题呢?类MI内必须有一个print(string);
void print(string) const ;
并让这个函数调用基类Base的print(string)。但是此处有一个问题:由于我们并没有使用虚拟继承,编译器并不知道我们究竟希望通过Derived1还是Derived2来调用print函数。所以,我们又修改Derived1,提供它自己的print(string)来调用Base的print(string)。
void Derived1::print(string s)
{
Base::print(s) ;
}
于是MI的print(string)函数可以写成:
void MI::print(string s)
{
Derived1::print(s) ;
}
注意,我们不能写成:
void MI::print(string s)
{
Derived1::Base::print(s) ;
}
因为Derived1::Base::print(s)被解释为取用Derived1内的嵌套类Base内的成员函数print。也就是上述语法指的不是继承关系,而是某个类型和嵌套类的关系。如果写成:
void MI::print(string s)
{
Base::print(s) ;
}
也无法正常工作,因为Base不是MI的直接基类。注意这一点:就是派生类不能直接调用间接基类的成员函数。只能调用直接基类的成员函数。要想调用间接基类的函数,必须先通过其直接基类,然后再在其直接基类中调用该间接基类。