多态&多态对象模型

本文探讨了多态的定义,包括其在运行时和编译时的体现,以及虚函数、抽象类、覆盖等实现多态的方法。通过实例展示了单继承、多继承及菱形继承(虚拟继承)的多态对象模型,分析了构成多态的必要条件。欢迎读者提出宝贵意见。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.什么多态? 

1.定义:

   多态按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。

    多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

   多态性在Object Pascal和C++中都是通过虚函数实现的。


2.表现形式:

    C++中的多态性具体体现在运行和编译两个方面。运行时多态是动态多态,其具体引用的对象在运行时才能确定。编译时多态是静态多态,在编译时就可以确定对象使用的形式。

    实现多态有以下方法:虚函数抽象类覆盖模板(重载和多态无关)。


3.构成条件:

   (1) 构成虚函数的重写(函数名,参数列表,返回值相同);

   (2) 父类的指针或引用调用虚函数;


下面举一个例子:

#include <iostream>
using namespace std;


class A
{
public:
	virtual void f()
	{
		cout<<"A::f()"<<endl;
	}
};

class B :public A
{
public:
	virtual void f()
	{
		cout<<"B::f()"<<endl;
	}
};

int main()
{
	A a;
	B b;
	A* p = &a;
	p->f();

	p = &b;
	p->f();

	return 0;
}

运行结果:

注:若构成多态,则跟对象有关;反之,跟类型有关。


二.多态的对象模型

1.单继承

class Base 
{ 
public :
	virtual void func1() 
	{          
		cout<<"Base::func1" <<endl;   
	}

	virtual void func2() 
	{         
		cout<<"Base::func2" <<endl;  
	}

private :     
	int a ; 
};
			  
class Derive :public Base 
{ 
public :     
	virtual void func1()    
	{          
		cout<<"Derive::func1" <<endl;   
	}
			  
	virtual void func3()    
	{          
		cout<<"Derive::func3" <<endl;    
	}
			  
	virtual void func4()    
	{         
		cout<<"Derive::func4" <<endl; 
	}

private :     
	int b ; 
};
							
typedef void (* FUNC)();
							
void PrintVTable (int* VTable) 
{     
	cout<<" 虚表地址>"<< VTable<<endl;						
	for (int i = 0; VTable[i] != 0; ++i)    
	{         
		printf(" 第%d个虚函数地址 :0X%x,->", i , VTable[i]); 
		FUNC f = (FUNC) VTable[i];  
		f();   
	}					
	cout<<endl; 
}

int main()
{
	Base b1 ;     
	Derive d1 ;
	int* VTable1 = (int*)(*(int*)&b1);     
	int* VTable2 = (int*)(*(int*)&d1);
	PrintVTable(VTable1);     
	PrintVTable(VTable2); 
}

运行结果:


我们打开监视窗口:



2.多继承

class Base1 
{ 
public :     
	virtual void func1()    
	{          
		cout<<"Base1::func1" <<endl;    
	}
	virtual void func2()    
	{          
		cout<<"Base1::func2" <<endl;    
	}

private :     
	int b1; 
};

class Base2 
{ 
public :     
	virtual void func1()    
	{          
		cout<<"Base2::func1" <<endl;    
	}	  
	virtual void func2()    
	{         
		cout<<"Base2::func2" <<endl;    
	}
			  
private :     
	int b2; 
};
							
class Derive : public Base1, public Base2 
{ 
public :    
	virtual void func1()					
	{         
		cout<<"Derive::func1" <<endl;   
	}					
	virtual void func3()    
	{          
		cout<<"Derive::func3" <<endl;   
	}
							
private :     
	int d1; 
};
										  
typedef void (* FUNC) ();
										  
void PrintVTable (int* VTable) 
{     
	cout<<" 虚表地址>"<< VTable<<endl ;
	for (int i = 0; VTable[i] != 0; ++i)    
	{         
		printf(" 第%d个虚函数地址 :0X%x,->", i , VTable[i]); 
		FUNC f = (FUNC) VTable[i];          
		f();   
	}								  
	cout<<endl; 
}
										  
int main()
{     
	Derive d1 ;
	int* VTable = (int*)(*( int*)&d1);								  
	PrintVTable(VTable);									  
    VTable = (int *)(*((int*)&d1 + sizeof (Base1)/4));     
	PrintVTable(VTable); 
	return 0;
}


运行结果:


监视窗口中:


3.菱形继承和菱形虚拟继承

         关于菱形继承菱形虚拟继承的介绍,可见我的这篇博客:

C++中的 菱形继承

class A
{
public:
	virtual void f1()
	{
		cout<<"A::f1"<<endl;
	}
	virtual void f2()
	{
		cout<<"A::f2"<<endl;
	}

public:
	int _a;
};

class B : virtual public A
{
public:
	virtual void f1()
	{
		cout<<"B::f1"<<endl;
	}

	virtual void f3()
	{
		cout<<"B::f3"<<endl;
	}
public:
	int _b;
};

class C : virtual public A
{
public:
	virtual void f1()
	{
		cout<<"C::f1"<<endl;
	}

	virtual void f3()
	{
		cout<<"C::f3"<<endl;
	}
public:
	int _c;
};

class D : public B, public C
{
public:
	virtual void f1()
	{
		cout<<"D::f1"<<endl;
	}

	virtual void f4()
	{
		cout<<"D::f4"<<endl;
	}
public:
	int _d;
};

typedef void(*VFUNC)();

void PrintVTable(void* vtable)
{
	printf("vtable:0x%p\n", vtable);
	VFUNC* array = (VFUNC*)vtable;
	for (size_t i = 0; array[i] != 0; ++i)
	{
		printf("vtable[%d]:0x%p->", i,array[i]);
		array[i]();
	}
	cout<<" "<<endl;
}

int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;
	// B
	PrintVTable(*((int**)&d));
	// C
	PrintVTable(*((int**)((char*)&d+sizeof(B)-sizeof(A))));
	// A
	PrintVTable(*((int**)((char*)&d+sizeof(B)+sizeof(C)-2*sizeof(A)+4)));
	return 0;
}


运行结果:


监视窗口中:


写得不好,希望大家多提宝贵意见啊!!!




           

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值