一.什么多态?
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.菱形继承和菱形虚拟继承
关于菱形继承和菱形虚拟继承的介绍,可见我的这篇博客:
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;
}
运行结果:
监视窗口中:
写得不好,希望大家多提宝贵意见啊!!!