第51课 C++ 对象模型分析(下)

本文内容来自于对狄泰学院 唐佐林老师 C++深度解析 课程的学习总结

继承对象模型

在 C++ 编译器的内部 类可以理解为结构体
子类是由 父类成员叠加子类新成员 得到的
在这里插入图片描述

下面我们来编写一段程序来验证

#include <iostream>

using namespace std;

class Parent
{
protected:
	int m_i;
	int m_j;
};

class Child : public Parent
{
public:
	int m_k;
};

int main()
{
	cout << "sizeof(Parent) = " << sizeof(Parent) << endl;
	cout << "sizeof(Child) = " << sizeof(Child) << endl;

	return 0;
}

运行结果
在这里插入图片描述

实验结果:子类继承了父类成员变量的内存空间





C++ 多态的实现原理

当类中 声明虚函数 时,编译器会在类中 生成一个虚函数表
虚函数表是一个 存储成员函数地址的数据结构
虚函数表是 由编译器自动生成与维护的
virtual 成员函数会被编译器 放入虚函数表中
存在虚函数时,每个对象都有一个指向虚函数表的指针

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


下面我们根据多态实现的原理,通过C语言来实现多态
通过结构体来模拟类,子类通过结构体包含来模拟继承关系,最终通过函数指针来实现多态
Demo.h

#ifndef _DEMO_H_
#define _DEMO_H_


typedef void Demo;

Demo *Demo_Creat(int i, int j);
int Demo_GetI(Demo *pthis);
int Demo_GetJ(Demo *pthis);
void Demo_Free(Demo *pthis);
int Demo_Add(Demo *pthis, int val);


typedef void Derived;

Derived *Derived_Creat(int i, int j, int k);
int Derived_GetI(Demo *pthis);
int Derived_GetJ(Demo *pthis);
int Derived_GetK(Demo *pthis);
int Derived_add(Derived *pthis, int val);

#endif

Demo.c

#include <stdio.h>
#include <malloc.h>
#include "Demo.h"



struct DemoClass
{
	struct VTable *pVtl;
	int m_i;
	int m_j;
};

struct DerivedClass
{
	struct DemoClass d;
	int m_k;
};


/* 虚拟列表*/
struct VTable 
{
	int (*pAdd)(void *, int);
};

static int Demo_Virtual_Add(Demo *pthis, int val);
static int Derived_Virtual_Add(Derived *pthis, int val);

/*父类虚函数列表 */
static struct VTable g_DemoVtal = {
	Demo_Virtual_Add
};

/* 子类虚拟函数列表 */
static struct VTable g_Virtual_Derived = {
	Derived_Virtual_Add
};




Demo* Demo_Creat(int i, int j)
{
	struct DemoClass *pthis = (struct DemoClass *)malloc(sizeof(struct DemoClass));
	if(pthis == NULL)
		return NULL;

	pthis->pVtl = &g_DemoVtal;
	pthis->m_i = i;
	pthis->m_j = j;

	return pthis;
}

int Demo_GetI(Demo *pthis)
{
	struct DemoClass *demo = (struct DemoClass *)pthis;
	return demo->m_i;
}

int Demo_GetJ(Demo *pthis)
{
	struct DemoClass *demo = (struct DemoClass *)pthis;
	return demo->m_j;
}

static int Demo_Virtual_Add(Demo *pthis, int val)
{
	struct DemoClass *demo = (struct DemoClass *)pthis;

	return (demo->m_i + demo->m_j + val);
}

int Demo_Add(Demo *pthis, int val)
{
	struct DemoClass *demo = (struct DemoClass *)pthis;

	return demo->pVtl->pAdd(pthis, val);
}

void Demo_Free(Demo *pthis)
{
	free(pthis);
}

Derived *Derived_Creat(int i, int j, int k)
{
	struct DerivedClass *Derv = (struct DerivedClass *)malloc(sizeof(struct DerivedClass));

	Derv->d.pVtl = &g_Virtual_Derived;
	Derv->d.m_i = i;
	Derv->d.m_j = j;
	Derv->m_k = k;

	return Derv;
}

int Derived_GetI(Demo *pthis)
{
	struct DerivedClass *Derv = (struct DerivedClass *)pthis;
	return Derv->d.m_i; 
}

int Derived_GetJ(Demo *pthis)
{
	struct DerivedClass *Derv = (struct DerivedClass *)pthis;
	return Derv->d.m_j; 
}

int Derived_GetK(Demo *pthis)
{
	struct DerivedClass *Derv = (struct DerivedClass *)pthis;
	return Derv->m_k; 
}

static int Derived_Virtual_Add(Derived *pthis, int val)
{
	struct DerivedClass *Derv = (struct DerivedClass *)pthis;

	return (Derv->d.m_i + Derv->d.m_j + Derv->m_k + val);
}

int Derived_add(Derived *pthis, int val)
{
	struct DerivedClass *Derv = (struct DerivedClass *)pthis;

	return Derv->d.pVtl->pAdd(pthis, val);
}

main.c

#include <stdio.h>
#include "Demo.h"

void run(Demo *pthis, int val)
{
	int ret = Demo_Add(pthis, val);
	printf("run: ret = %d\n", ret);
}

int main(void)
{
	Demo *classdemo = Demo_Creat(1, 2);

	int i = Demo_GetI(classdemo);
	int j = Demo_GetJ(classdemo);

	printf("i = %d\n", i);
	printf("j = %d\n", j);

	Derived *classderived = Derived_Creat(10, 20, 30);

	int ret = Demo_Add(classdemo, 3);
	printf("Demo_Add: ret = %d\n", ret);

	ret = Derived_add(classderived, 40);
	printf("Derived_add: ret = %d\n", ret);

	run(classdemo, 3);
	run(classderived, 40);

	Demo_Free(classderived);
	Demo_Free(classdemo);

	return 0;
}

运行结果:
在这里插入图片描述

实验结果:run 函数实现了多态特性,通过父类子类对象指针的传入,实现了对应的对象功能




小结

继承的本质就是 父子间成员变量的叠加
C++ 中的多态是 通过虚函数表实现的
虚函数表是 由编译器自动生成与维护的
虚函数的调用效率 低于 普通成员函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzg2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值