C++ | 【03】类的【继承、多态、复合、委托】
一、虚函数表
当改类中存在虚函数 或其基类 含有虚函数 ,编译器将会添加一个虚函数表vptr ;
1、简介
只要在类中定义了virtual 函数当创建对象时,编译器会自动给对象添加一个vptr指针,指向虚函数表;
#include <iostream>
using namespace std;
class A {
A() {}
~A(){}
void func();
int m_a;
};
class B {
B() {}
~B(){}
virtual void func(){};
int m_a;
};
int main() {
cout << "class sizeof(A) no virtual func:" << sizeof(A) << endl;
cout << "class sizeof(B) with virtual func:" << sizeof(B) << endl;
return 0;
}
2、虚函数
一个函数在类中声明时,在头部加上virtual 即被声明为虚函数;
类中虚函数与vpbl的关系
3、使用多态时如何通过指针找到对应虚函数
当虚继承时,一般说来,派生类地址 和其虚基类地址 之间的偏移量是不固定 的,因为如果这个派生类 又被进一步继承的话,最终派生类会把共享 的虚基类实例数据放到一个与上一层派生类 不同的偏移量 处;
#include <iostream>
using namespace std;
class Animal{
public:
virtual void do_sm(){
};
virtual void cry(){
};
virtual void fly(){
};
private:
string m_name;
};
class woodpecker : public Animal {
public:
virtual void do_sm() override {
cout << "woodpecker do ...." << endl;
}
virtual void cry() override {
cout << "woodpecker cry ...." << endl;
}
virtual void fly() override {
cout << "woodpecker fly ...." << endl;
}
void peck_wood() {
cout << "woodpecker peck_wood ...." << endl;
}
private:
int m_weight;
};
class chicken : woodpecker {
public:
virtual void do_sm() override {
cout << "chicken do ...." << endl;
}
virtual void cry() override {
cout << "chicken cry ...." << endl;
}
void lay_egg(){
cout << "chicken lay_egg ...." << endl;
}
private:
string m_name;
int m_canLayEggs;
};
int main() {
typedef void(*Func)(void);
woodpecker w;
int* obj = (int*)&w;
int* vp = (int*)*obj;
Func f1 = (Func)vp[0];
Func f2 = (Func)vp[1];
Func f3 = (Func)vp[2];
f1();
f2();
f3();
return 0;
}
|