C++ 类型兼容规则

类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。 通过公有继承,派生类得到了基类中除构造函数和析构函数之外的所有成员。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。类型兼容规则中指的替代包括以下的情况:

(1)派生类的对象可以隐含转换为基类对象
(2)派生类的对象可以初始化基类的引用
(3)派生类的指针可以隐含转换为基类的指针

在替代之后,派生类对象就可以作为基类对象使用,但只能使用从基类继承的成员。

如果B类为基类,D为B的公有派生类,则D类中包含了基类B中除构造函数和析构函数之外的所有成员。这时根据类型兼容规则,在基类B的对象可以出现在任何地方,都可以用派生类D的对象来替代。

在如下程序中,b1为B类的对象,d1为D类的对象

class B{
    
    ...};
class D:public B{
    
    ...};

B b1;
B *p1;
D d1;

这时:
(1)派生类对象可以隐含转换为基类对象,即用派生类对象中从基类继承来的成员,逐个赋值给基类对象成员:

b1=d1;

(2)派生类对象也可以初始化基类对象的引用:

B &rb=d1;

(3)派生类对象的地址可以隐含转换为指向基类的指针:

p1=&d1;

由于类型兼容规则的引入,对于基类及其公有派生类对象,可以使用相同的函数统一处理。因为当函数的形参为基类的对象(或引用、指针)时,实参可以是派生类的对象(或指针),而没有必要为每一个类设计单独的模块,大大提高了程序效率。

【例】类型兼容规则实例
基类A以公有继承方式派生出B类,B类再作为基类以公有继承方式派生出C类。基类A中定义了成员函数display(),在派生类中对这个成员函数进行了隐藏。

class A//基类A定义
{
    
    
public:
	void display()const
	{
    
    
		cout << "显示类A" << endl;
	}
};

class B :public A//公有派生类B定义
{
    
    
public:
	void display()const
	{
    
    
		cout << "显示类B" << endl;
	}
};

class C :public B//公有派生类C定义
{
    
    
public:
	void display()const
	{
    
    
		cout << "显示类C" << endl;
	}
};

void fun(A* p)//参数为指向基类A的对象的指针
{
    
    
	p->display();//"对象指针->成员名"
}

int main()
{
    
    
	A a;
	B b;
	C c;

	fun(&a);
	fun(&b);
	fun(&c);

	return 0;
}

运行结果:
在这里插入图片描述
这样,通过“对象名.成员名”或者“对象指针->成员名”的方式,就应该可以访问到各派生类中继承自基类的成员。虽然根据类型兼容规则,可以将派生类对象的地址赋值给基类A的指针,但是通过这个基类类型的指针,却只能访问到从基类继承的成员。

在程序中,声明了一个形参为基类A类型的指针的普通函数fun,根据类型兼容兼容规则,可以将公有派生类对象的地址赋值给基类类型的指针,这样,使用fun函数就可以同一对这个类族中的对象进行操作。在程序运行过程中,分别把基类对象、派生类B的对象和派生类C的对象的地址赋值给基类类型的指针p,但是通过p,只能使用继承下来的基类成员。也就是说,尽管指针指向派生类C的对象,fun函数运行时通过这个指针只能访问到C类从基类A继承过来的成员函数display,而不是C类自己的同名成员函数。因此,主函数中3次调用fun的结果是相同的——访问了基类的公有成员函数。

通过这个例子可以看出,根据类型兼容规则,可以在基类对象出现的任何场合使用派生类对象进行替代,但是替代之后派生类对象仅仅发挥出基类对象的作用。

猜你喜欢

转载自blog.csdn.net/NuYoaH502329/article/details/132123130
今日推荐