类型兼容规则
通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。
一个公有派生类的对象在使用上可以被当作基类的对象
- 派生类的对象可以隐含转换为基类对象;
- 派生类的对象可以初始化基类的引用;
- 派生类的指针可以隐含转换为基类的指针;
通过基类对象名、指针只能使用从基类继承的成员
#include <iostream>
using namespace std;
class Base1 { //基类Base1定义
public:
void display() const
{
cout << "Base1::display()" << endl;
}
};
class Base2 : public Base1 { //公有派生类Base2定义
public:
void display() const
{
cout << "Base2::display()" << endl;
}
};
class Derived : public Base2 { //公有派生类Derived定义
public:
void display() const
{
cout << "Derived::display()" << endl;
}
};
void fun(Base1 *ptr)
{ //参数为指向基类对象的指针
ptr->display(); //"对象指针->成员名"
}
int main() { //主函数
Base1 base1; //声明Base1类对象
Base2 base2; //声明Base2类对象
Derived derived; //声明Derived类对象
fun(&base1); //用Base1对象的指针调用fun函数
fun(&base2); //用Base2对象的指针调用fun函数
fun(&derived); //用Derived对象的指针调用fun函数
return 0;
}
运行结果:
Base1::display()
Base1::display()
Base1::display()
同名隐藏规则
当派生类与基类中有相同成员时:
- 若未强行指名,则通过派生类对象使用的是派生类中的同名成员;
- 如要通过派生类对象访问基类中被隐藏的同名成员,应使用基类名限定。
#include <iostream>
using namespace std;
class Base1 { //定义基类Base1
public:
int var;
void fun() { cout << "Member of Base1" << endl; }
};
class Base2 { //定义基类Base2
public:
int var;
void fun() { cout << "Member of Base2" << endl; }
};
class Derived : public Base1, public Base2 { //定义派生类Derived
public:
int var; //同名数据成员
void fun() { cout << "Member of Derived" << endl; } //同名函数成员
};
int main() {
Derived d;
Derived *p = &d;
d.var = 1; //对象名.成员名标识
d.fun(); //访问Derived类成员
d.Base1::var = 2; //作用域分辨符标识
d.Base1::fun(); //访问Base1基类成员
p->Base2::var = 3; //作用域分辨符标识
p->Base2::fun(); //访问Base2基类成员
return 0;
}
运行结果
Member of Derived
Member of Base1
Member of Base2