1:所谓多态就是多种形态,在两个类中,函数名相同的函数,通过不同对象的调用,产生不同的结果。多态和类型无关,只和对象有关。
构成多态的条件:(1)虚函数的重写:子类中和父类相同点的虚函数
(2)父类的指针/引用调用虚函数
当指向父类的指针或引用调用重写的虚函数时,当指向父类调用的就是父类的虚函数,当指向子类调用的就是子类的虚函数。
2:多态的对象模型
单继承
class Base
{
public:
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
private:
int a;
};
class Derive:public Base
{
public:
virtual void fun1()
{
cout<<"Derive::fun1()"<<endl;
}
virtual void fun3()
{
cout<<"Derive::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Derive::fun4()"<<endl;
}
private:
int b;
};
int main()
{
Base b;
Derive d;
int* vtable1 = (int*)(*(int*)&b);
int* vtable2 = (int*)(*(int*)&d);
PrintVTable(vtable1);
PrintVTable(vtable2);
return 0;
}
typedef void(* FUNC)();//函数指针(指向函数的指针)
void PrintVTable(int* VTable)//打印虚函数表
{
cout<<"VTable: "<<VTable<<endl;
for(int i=0; VTable[i] != 0; ++i)
{
printf("VTable[i]: 0x%x,->",i,VTable[i]);
FUNC f = (FUNC)VTable[i];
f();
}
cout<<endl;
}
多继承
class AA
{
public:
virtual void fun1()
{
cout<<"AA::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"AA::fun2()"<<endl;
}
private:
int _a;
};
class BB
{
public:
virtual void fun1()
{
cout<<"BB::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"BB::fun2()"<<endl;
}
private:
int _b;
};
class CC : public AA,public BB
{
public:
virtual void fun1()
{
cout<<"CC::fun1()"<<endl;
}
virtual void fun3()
{
cout<<"CC::fun3()"<<endl;
}
private:
int _c;
};
typedef void(*FUNC)();
void PrintVTable(int* VTable)
{
cout<<"VTable: "<<VTable<<endl;
for(int i=0; VTable[i] != 0; ++i)
{
printf("VTable[i]:0x%x,->",i,VTable[i]);
FUNC f = (FUNC)VTable[i];
f();
}
cout<<endl;
}
int main()
{
CC c;
int* vtable = (int*)(*(int*)&c);
PrintVTable(vtable);
vtable = (int*)(*((int*)&c+sizeof(AA)/4));
//sizeof(AA)=8除4为int*的个数
PrintVTable(vtable);
return 0;
}
**菱形继承
//菱形继承的多态对象模型
class A
{
public:
virtual void fun1()
{
cout<<"A::fun1()"<<endl;
}
public:
int _a;
};
class B : public A
{
public:
virtual void fun1()
{
cout<<"B::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"B::fun2()"<<endl;
}
public:
int _b;
};
class C : public A
{
public:
virtual void fun1()
{
cout<<"C::fun1()"<<endl;
}
virtual void fun3()
{
cout<<"C::fun3()"<<endl;
}
public:
int _c;
};
class D : public B,public C
{
public:
virtual void fun1()//重写B,C中的虚函数
{
cout<<"D::fun1()"<<endl;
}
virtual void fun2()//重写B中的虚函数
{
cout<<"D::fun2()"<<endl;
}
virtual void fun4()//D中的虚函数
{
cout<<"D::fun4()"<<endl;
}
public:
int _d;
};
typedef void(*FUNC)();
void PrintVTable(int* VTable)
{
cout<<"VTable: "<<VTable<<endl;
for(int i=0; VTable[i] != 0; ++i)
{
printf("VTable[%d]:0x%x,->",i,VTable[i]);
FUNC f = (FUNC)VTable[i];
f();
}
cout<<endl;
}
int main()
{
D d;
d.B::_a = 1;
d._b = 2;
d.C::_a = 3;
d._c = 4;
d._d = 5;
int* vtable = (int*)(*(int*)&d);
PrintVTable(vtable);
vtable = (int*)(*((int*)&d+sizeof(B)/4));
PrintVTable(vtable);
return 0;
}
总结:D中的虚函数放在第一个继承基类的虚函数表中,B中会放D中重写的虚函数和自己的虚函数,C中会放D中重写的虚函数和自己的虚函数。
菱形虚拟继承**
//菱形虚拟继承的多态对象模型
class A
{
public:
virtual void fun1()
{
cout<<"A::fun1()"<<endl;
}
public:
int _a;
};
class B : virtual public A
{
public:
virtual void fun1()
{
cout<<"B::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"B::fun2()"<<endl;
}
public:
int _b;
};
class C : virtual public A
{
public:
virtual void fun1()
{
cout<<"C::fun1()"<<endl;
}
virtual void fun3()
{
cout<<"C::fun3()"<<endl;
}
public:
int _c;
};
class D : public B,public C
{
public:
virtual void fun1()//重写B,C中的虚函数
{
cout<<"D::fun1()"<<endl;
}
virtual void fun2()//重写B中的虚函数
{
cout<<"D::fun2()"<<endl;
}
virtual void fun4()//D中的虚函数
{
cout<<"D::fun4()"<<endl;
}
public:
int _d;
};
typedef void(*FUNC)();
void PrintVTable(int* VTable)
{
cout<<"VTable: "<<VTable<<endl;
for(int i=0; VTable[i] != 0; ++i)
{
printf("VTable[%d]:0x%x,->",i,VTable[i]);
FUNC f = (FUNC)VTable[i];
f();
}
cout<<endl;
}
int main()
{
D d;
d._a = 1;
d._b = 2;
d._c = 4;
d._d = 5;
int* vtable = (int*)(*(int*)&d);//B的虚函数表
PrintVTable(vtable);
vtable = (int*)(*((int*)&d+3));//C的虚函数表
PrintVTable(vtable);
vtable = (int*)(*((int*)&d+7));//A的虚函数表
PrintVTable(vtable);
return 0;
}