作者:阿莱沃_132 | 来源:互联网 | 2023-05-31 19:59
多重继承的继承列表中,一个基类只能出现一次。先看一个例子:#include<iostream>usingnamespacestd;classZooAnimal{p
多重继承的继承列表中,一个基类只能出现一次。先看一个例子:
#include
using namespace std;
class ZooAnimal
{
public:
ZooAnimal()
{
cout <<"ZooAnimal" << endl;
}
ZooAnimal(int data)
{
cout <<"ZooAnimal(int data)" << endl;
d1 = data;
}
private:
int d1;
};
class Bear: public ZooAnimal
{
public:
Bear()
{
cout <<"Bear" << endl;
}
Bear(int data)
{
cout <<"Bear(int data)" << endl;
d2 = data;
}
private:
int d2;
};
class Endangered
{
public:
Endangered()
{
cout <<"Endangered" << endl;
}
Endangered(int data)
{
cout <<"Endangered(int data)" << endl;
d3 = data;
}
private:
int d3;
};
class Panda: public Bear, public Endangered
{
public:
Panda()
{
cout <<"Panda" << endl;
}
Panda(int data):Endangered(data), Bear(data)
{
cout <<"Panda(int data)" << endl;
d4 = data;
}
private:
int d4;
};
int main(void)
{
Panda panda(10);
return 0;
}
1、派生类构造函数初始化所有基类
// explicitly initialize both base classes
Panda::Panda(int data):Bear(data), Endangered(data){}
// implicitly use Bear default constructor to initialize base Bear
Panda::Panda(int data):Endangered(data){}
2、构造的次序
构造函数的初始化列表只能控制用于初始化基类的值,不能控制基类的构造次序。基类的构造函数是按照基类的继承顺序被调用的
class Panda: public Bear, public Endangered,即对Panda而言,基类初始化的顺序:
(1)ZooAnimal
(2)Bear
(3)Endangered
(4)Panda
3、析构的次序
总是按照构造函数运行的逆序调用析构函数,即~Panda(),~Endangered(),~Bear(),~ZooAnimal()
4、多重继承下的类作用域
在多重继承下,成员函数中使用的名字的查找首先在函数本身进行,如果不能在本地找到名字,就继续在成员的类中查找,然后依次查找每个基类。在多重继承下,查找同时检查所有的基类继承子树---在我们的例子中,并行查找Endangered子树和Bear/ZooAnimal子树。如果在多个子树中找到改名字,则那个名字的使用必须显示的指定使用哪个基类;否则,该名字的使用是二义性的。
假定Bear类和Endangered类都定义了一个print函数,而Panda类没有定义该函数,则 Panda panda; panda.print();这样的语句将导致编译时错误。Panda类有两个print函数是完全合法的。派生只是导致潜在的二义性,如果没有Panda对象调用print,那就可以避免二义性。如果每个print调用明确指出想要哪个版本--Bear::print还是Endangered::print,也可以避免错误。只有在存在使用该成员的二义性尝试的时候,才会出错。
函数调用时首先发生名字查找。虽然两个继承的print成员的二义性相当明显,但是也许更令人惊讶的是,即使两个继承的函数有不同的形参表,也会产生错误。类似的,即使函数在一个类中是私有的而在另一个类中是公用的或受保护的,也是错误的。最后,如果在ZooAnimal类中定义了print而在Bear类中没有定义,调用仍是错误的。