【C++】 51_C++对象模分析 (下)

37次阅读

共计 2074 个字符,预计需要花费 6 分钟才能阅读完成。

继承对象模型

在 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++ 中的多态是通过虚函数表实现的
虚函数表是由编译器自动生成与维护的
虚函数的调用效率低于普通函数

以上内容参考狄泰软件学院系列课程,请大家保护原创!

正文完
 0