继承对象模型
在 C++ 编译器的内部类可以理解为结构体
子类是由父类成员叠加子类新成员得到的
class Dervied : public Demo
{
int mk;
};
编程实验:继承对象模型初探
#include <iostream>
using namespace std;
class Demo
{
protected:
int mi;
int mj;
};
class Derived : public Demo
{
private:
int mk;
public:
Derived(int i, int j, int k)
{
mi = i;
mj = j;
mk = k;
}
void print()
{
cout << “mi = ” << mi << “, ”
<< “mj = ” << mj << “, ”
<< “mk = ” << mk << endl;
}
};
struct Test
{
int mi;
int mj;
int mk;
};
int main()
{
cout << “sizeof(Demo) = ” << sizeof(Demo) << endl;
cout << “sizeof(Derived) = ” << sizeof(Derived) << endl;
Derived d(1, 2, 3);
Test* p = reinterpret_cast<Test*>(&d); // 注意这里!
cout << “Befor changeing …” << endl;
d.print();
p->mi = 10; // 注意这里!
p->mj = 20;
p->mk = 30;
cout << “After changeing …” << endl;
d.print();
return 0;
}
输出:
sizeof(Demo) = 8
sizeof(Derived) = 12
Befor changeing …
mi = 1, mj = 2, mk = 3
After changeing …
mi = 10, mj = 20, mk = 30
结论:
子类是由父类成员叠加子类新成员得到的
多态对象模型
C++ 多态的实现原理
当类中声明虚函数时,编译器会在类中生成一个虚函数表
虚函数表是一个存储成员函数地址的数据结构
虚函数表由编译器自动生成与维护
virtual 成员函数被编译器放入虚函数表中
存在虚函数时,每个对象都有一个指向虚函数表的指针
多态:面向对象理论中的概念,与程序设计语言无关虚函数:C++ 中实现多态的唯一方式
class Demo
{
private:
int mi;
int mj;
public:
virtual int add(int value)
{
return mi + mj + value;
};
};
==>
class Derived : public Demo
{
private:
int mk;
public:
virtual int add(int value)
{
return mk + value;
}
};
==>
void run(Demo* p, int v)
{
p->add(v);
}
编译器确认 add() 是否为虚函数?
Yes -> 编译器在对象 VPTR 所指向的虚函数表中查找 add() 的地址
No -> 编译器可以直接确定被调成员函数的地址
调用效率:虚函数 < 普通成员函数
编程实验:多态对象模型初探
#include <iostream>
using namespace std;
class Demo
{
protected:
int mi;
int mj;
public:
virtual void print()
{
cout << “mi = ” << mi << “, ”
<< “mj = ” << mj << endl;
}
};
class Derived : public Demo
{
private:
int mk;
public:
Derived(int i, int j, int k)
{
mi = i;
mj = j;
mk = k;
}
void print()
{
cout << “mi = ” << mi << “, ”
<< “mj = ” << mj << “, ”
<< “mk = ” << mk << endl;
}
};
struct Test
{
void* p; // 注意这里!
int mi;
int mj;
int mk;
};
int main()
{
cout << “sizeof(Demo) = ” << sizeof(Demo) << endl; // 注意这里!
cout << “sizeof(Derived) = ” << sizeof(Derived) << endl;
Derived d(1, 2, 3);
Test* p = reinterpret_cast<Test*>(&d);
cout << “Befor changeing …” << endl;
d.print();
p->mi = 10;
p->mj = 20;
p->mk = 30;
cout << “After changeing …” << endl;
d.print();
return 0;
}
输出:
sizeof(Demo) = 12
sizeof(Derived) = 16
Befor changeing …
mi = 1, mj = 2, mk = 3
After changeing …
mi = 10, mj = 20, mk = 30
虚函数表指针位于对象最开始的 4 个字节处(32 位平台)
编程实验:多态本质分析
C 写面向对象、继承与多态
小结
继承的本质就是父子间成员变量的叠加
C++ 中的多态是通过虚函数表实现的
虚函数表是由编译器自动生成与维护的
虚函数的调用效率低于普通函数
以上内容参考狄泰软件学院系列课程,请大家保护原创!