如果你以精通 c/c++ 作为自己的技能标签,那么该如何回答这样一道深入底层的问题呢?如果毫无准备地面对这个问题,可能无法做出高分的回答。
这道题的意义并不在实现层面,因为我们的工作内容大概率不会是去开发一个语言,但是考虑并动手去做这个题则能帮助我们掌握c的高级用法并且深入理解c++的实现机理。
首先 c++的三大特性:封装 继承 多态
封装了什么?将属性和方法封装到一个class中,对应c的struct只是属性的结合,但是属性可以是指针啊,函数指针也是可以指向一个可以调用的方法的。
继承 c的struct是支持嵌套的,这里只考虑public继承,public继承模塑的是is-a的关系,从内存结构上来看,子类继承基类,相当于在子类中存储了一个基类对象,这个对象存储在子类数据的起始位置,这样才能保证在可以使用基类的地方都可以使用子类,也从内存层面说明继承是侵入的,在使用继承时应该多考虑一下: 组合优于继承
多态 可以实现指针数组来模拟c++的虚函数表,另外函数指针做函数参数,这要比多态还灵活。
简短总结一下:封装用函数指针实现 继承用结构体嵌套 多态可以自己写虚函数表,也可以函数指针做函数参数实现更灵活的多态。
下面代码我用c实现了一个template method模式 ,包含了这个问题中的所有
#include#include typedef void(*funcP)(void*); typedef int*(*virTabPointer)[2]; //这是一个指针 typedef struct Animal { //指向虚函数表的指针 virTabPointer m_virPointer; //funcP m_funcPointer; char m_name[20]; }Animal; typedef struct Tiger { Animal m_base; int m_age; }Tiger; typedef struct Bull { Animal m_base; char m_sex[6]; }Bull; void SayName(void* this) { Animal* thisA = (Animal*)(this); printf("我的名字是:%sn", thisA->m_name); } void TigerEat(void* this) { Animal* thisA = (Animal*)(this); printf("我的名字是:%s,", thisA->m_name); Tiger* thisTiger = (Tiger*)(this); printf("今年%d岁,我吃肉n", thisTiger->m_age); } void BullEat(void* this) { Animal* thisA = (Animal*)(this); printf("我的名字是:%s,", thisA->m_name); Bull* thisBull = (Bull*)(this); printf("我的性别是:%s,我吃草n", thisBull->m_sex); } void TemplateFunc(Animal* obj) { //do something int** tempIntPointer = (int**)(obj); virTabPointer tempVTab = (virTabPointer)(*tempIntPointer); funcP tempFuncAddress = (funcP)((*tempVTab)[1]); tempFuncAddress(obj); //do something } //指针的数组,数组中的所有元素都是指针,是个数组 //a、指针数组:是指一个数组里面装着指针,也即指针数组是一个数组; //b、 数组指针,是个指针,这个指针指向数组 //定义的时候我不知道指针类型是什么,索性就定义成int* 了 int* animalVirTab[2] = {(int*)&SayName,NULL}; int* tigerVirTab[2] = { (int*)&SayName,(int*)&TigerEat }; //有几个虚函数元素长度就是几 int* bullVirTab[2] = {(int*)&SayName,(int*)&BullEat}; //有几个虚函数元素长度就是几 int main() { Animal* basePointer = NULL; //基类的指针 Tiger tigerA; basePointer = (Animal*)&tigerA; strcpy_s(basePointer->m_name,20, "老虎"); basePointer->m_virPointer = &tigerVirTab; tigerA.m_age = 5; TemplateFunc(basePointer); Bull bullA; basePointer = (Animal*)&bullA; strcpy_s(basePointer->m_name, 20,"牛"); basePointer->m_virPointer = &bullVirTab; strcpy_s(bullA.m_sex,6, "男"); TemplateFunc(basePointer); while (1); return 0; }



