《C++多态的对象模型之单/多继承、菱形/菱形虚拟继承》
程序员文章站
2024-03-22 23:48:28
...
多态:
多态的两个必要条件:①子类中必须重写父类中的虚函数。②父类的引用/指针依据指向的不同对象(父类或者子类)来调用不同的虚函数。即:父类的指针或引用指向父类时,调用父类的虚函数。父类的指针或引用指向子类时,调用子类的虚函数。
多态的单/多继承对象模型:
单继承:
//单继承
#include<iostream>
using namespace std;
typedef void(*VFPTR)();//VFPTR-->函数指针。
class A
{
public:
virtual void fun1()
{
cout << "virtual void A::fun1()" << endl;
}
virtual void fun2()
{
cout << "virtual void A::fun2()" << endl;
}
public:
int _a;
};
class B :public A
{
public:
virtual void fun1()//virtual可写可不写
{ //,因为fun1()在子类中仍然保持虚函数特性。
cout << "virtual void B::fun1()" << endl;
}
virtual void fun2()
{
cout << "virtual void B::fun2()" << endl;
}
public:
int _b;
};
void PrintVfptr(VFPTR* pvfptr)//形参为指向函数指针的指针,
{ //此函数功能为:打印虚表中存储的函数指针,并调用该函数。
size_t i = 0;
printf("虚表地址:%p\n", pvfptr);
while (pvfptr[i] != 0)
{
printf("第%d个虚函数地址为:%p-->", i + 1, pvfptr[i]);
pvfptr[i]();
i++;
}
}
int main()
{
B b;
b._a = 1;
b._b = 2;
PrintVfptr((VFPTR*)(*((int*)&b)));
return 0;
}
多继承:
//多继承
#include<iostream>
using namespace std;
typedef void(*VFPTR)();//VFPTR-->函数指针。
class A
{
public:
virtual void fun1()
{
cout << "virtual void A::fun1()" << endl;
}
virtual void fun2()
{
cout << "virtual void A::fun2()" << endl;
}
public:
int _a;
};
class B
{
public:
virtual void fun1()
{
cout << "virtual void B::fun1()" << endl;
}
virtual void fun3()
{
cout << "virtual void B::fun3()" << endl;
}
public:
int _b;
};
class C:public A,public B
{
public:
virtual void fun1()
{
cout << "virtual void C::fun1()" << endl;
}
virtual void fun4()
{
cout << "virtual void C::fun4()" << endl;
}
public:
int _c;
};
void PrintVfptr(VFPTR* pvfptr)
{
size_t i = 0;
printf("虚表地址:%p\n", pvfptr);
while (pvfptr[i] != 0)
{
printf("第%d个虚函数地址为:%p-->", i + 1, pvfptr[i]);
pvfptr[i]();
i++;
}
}
int main()
{
C c;
c._a = 1;
c._b = 2;
c._c = 3;
PrintVfptr((VFPTR*)(*((int*)&c)));
PrintVfptr((VFPTR*)(*((int*)((char*)&c + sizeof(A)))));
return 0;
}
多态的菱形/菱形虚拟继承对象模型:
菱形继承:
//菱形继承
#include<iostream>
using namespace std;
typedef void(*VFPTR)();//VFPTR-->函数指针。
class A
{
public:
virtual void fun1()
{
cout << "virtual void A::fun1()" << endl;
}
virtual void fun2()
{
cout << "virtual void A::fun2()" << endl;
}
public:
int _a;
};
class B :public A
{
public:
virtual void fun1()
{
cout << "virtual void B::fun1()" << endl;
}
virtual void fun3()
{
cout << "virtual void B::fun3()" << endl;
}
public:
int _b;
};
class C :public A
{
public:
virtual void fun1()
{
cout << "virtual void C::fun1()" << endl;
}
virtual void fun4()
{
cout << "virtual void C::fun4()" << endl;
}
public:
int _c;
};
class D :public B,public C
{
public:
virtual void fun1()
{
cout << "virtual void D::fun1()" << endl;
}
virtual void fun5()
{
cout << "virtual void D::fun5()" << endl;
}
public:
int _d;
};
void PrintVfptr(VFPTR* pvfptr)//形参为指向函数指针的指针,
{ //此函数功能为:打印虚表中存储的函数指针,并调用该函数。
size_t i = 0;
printf("虚表地址:%p\n", pvfptr);
while (pvfptr[i] != 0)
{
printf("第%d个虚函数地址为:%p-->", i + 1, pvfptr[i]);
pvfptr[i]();
i++;
}
}
int main()
{
D d;
d.B::_a = 1;
d.C::_a = 2;
d._b = 3;
d._c = 4;
d._d = 5;
PrintVfptr((VFPTR*)(*((int*)&d)));
PrintVfptr((VFPTR*)(*((int*)((char*)&d + sizeof(B)))));
return 0;
}
菱形虚拟继承:
//菱形虚拟继承
#include<iostream>
using namespace std;
typedef void(*VFPTR)();//VFPTR-->函数指针。
class A
{
public:
virtual void fun1()
{
cout << "virtual void A::fun1()" << endl;
}
virtual void fun2()
{
cout << "virtual void A::fun2()" << endl;
}
public:
int _a;
};
class B :virtual public A
{
public:
virtual void fun1()
{
cout << "virtual void B::fun1()" << endl;
}
virtual void fun3()
{
cout << "virtual void B::fun3()" << endl;
}
public:
int _b;
};
class C :virtual public A
{
public:
virtual void fun1()
{
cout << "virtual void C::fun1()" << endl;
}
virtual void fun4()
{
cout << "virtual void C::fun4()" << endl;
}
public:
int _c;
};
class D :public B, public C
{
public:
virtual void fun1()
{
cout << "virtual void D::fun1()" << endl;
}
virtual void fun5()
{
cout << "virtual void D::fun5()" << endl;
}
public:
int _d;
};
void PrintVfptr(VFPTR* pvfptr)//形参为指向函数指针的指针,
{ //此函数功能为:打印虚表中存储的函数指针,并调用该函数。
size_t i = 0;
printf("虚表地址:%p\n", pvfptr);
while (pvfptr[i] != 0)
{
printf("第%d个虚函数地址为:%p-->", i + 1, pvfptr[i]);
pvfptr[i]();
i++;
}
}
int main()
{
D d;
d._a = 1;
d._b = 2;
d._c = 3;
d._d = 4;
int size_A = sizeof(A);
cout << "size_A = " << size_A << endl;
int size_B = sizeof(B);
cout << "size_B = " << size_B << endl;
int size_C = sizeof(C);
cout << "size_C = " << size_C << endl;
int size_D = sizeof(D);
cout << "size_D = " << size_D << endl;
PrintVfptr((VFPTR*)(*((int*)&d)));
PrintVfptr((VFPTR*)(*((int*)((char*)&d + (size_B - size_A)))));
PrintVfptr((VFPTR*)(*((int*)((char*)&d + (size_D - size_A)))));
return 0;
}
总结:
菱形的虚拟继承为单/多继承对象模型、虚拟继承对象模型的综合。
下一篇: c++多态对象模型:单继承,多继承