从C++对象模型谈C语言的继承与多态

C++对象模型

C++类中一般包含两种数据成员和三中函数成员

  • 非静态数据成员
  • 静态数据成员
  • 非静态成员函数
  • 静态成员函数
  • 虚函数
    在类的每个实例化对象中,只包含两种数据,非静态数据成员指向虚函数表(virtual table)的指针(vptr)

继承的内存模型

在不考虑多态的情况下,也就只考虑继承过程中的非静态数据成员的内存模型就可以了。
在C++中,每个子类对象的内存空间中包含所有的父类的非静态数据成员。

base class data
other data members

C语言继承实现

只要实现和C++继承一样的内存模型就可以了

typedef struct _base {
	float x;
} Base;

typedef struct _D {
	Base base;
	float y;
}D;

D *new_D() { ... return x; }

这样形成的内存模型就符合要求了。

Base * base = (Base *)new_D();

C语言多态实现

C++使用虚函数实现的动态多态,是在运行时根据类型进行判断绑定的。
C语言要实现多态,就需要在创建时手动绑定了。

C语言继承与多态示例

#include <stdio.h>
#include <stdlib.h>

typedef void (*func)(void);

// 模拟虚函数表
struct _vptr {
	func foo;
};

// 基类
typedef struct _base {
	float x;
	struct _vptr *vptr;
} Base;

// 继承Base
typedef struct _A {
	Base base;
	float a;
}A;
// 继承Base
typedef struct _B {
	Base base;
	float b;
}B;

// 根据内存模型和截断规则,无论继承多少层都可以使用该宏直接访问'虚函数表'
#define VPTR(ob) (((Base *)(ob))->vptr)

void A_foo()
{
	printf("<type 'A'>\n");
}
void B_foo()
{
	printf("<type 'B'>\n");

}

struct _vptr A_vptr = { A_foo };
struct _vptr B_vptr = { B_foo };

// 构造函数
A * new_A()
{
	A * a = (A*)malloc(sizeof(A));
	VPTR(a) = &A_vptr;
	return a;
}

B * new_B()
{
	B * b = (B*)malloc(sizeof(B));
	VPTR(b) = &B_vptr;
	return b;
}

// 释放,相当于析构函数
void _delete(void * ptr) { free(ptr); }

///
// 使用
int main(void)
{
	A * a = new_A();
	B * b = new_B();

	Base * base_A = (Base *)a;
	Base * base_B = (Base *)b;

	base_A->vptr->foo();
	base_B->vptr->foo();

	_delete(a);
	_delete(b);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值