C模拟C++的对象模型初探

学C++有段时间了,对于C++的对象模型终于有了一些自己的理解。欢迎各位批评指正!

这里特别鸣谢传智播客的传智扫地僧老师,谢谢您!

以下是我实现对象模型的一些注释文档(部分),各位若感兴趣请留言,我可以提供实现两个类之间继承的完整版源代码

/*/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

一、C模拟C++对象模型中的关键技术说明:
    1.主要利用C语言函数指针的类型检查不严格,或者说使用C的函数指针的语法特点
        以下代码是对多态的简单模拟(VS2012 DEBUG和RELEASE环境下都能编译通过):

//********************
#ifdef __cplusplus
extern "C"{
#endif 

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

typedef struct{
	int (*vfun)();
}vir1;
typedef struct{
	vir1 *ptr;
	int a;
}A;

int test1(A* this,int m,int n)
{
	return m+n;
}

//********************
typedef struct{
	int (*vfun)();
}vir2;
typedef struct{
	vir2 *ptr;
	int a;
	int b;
}B;

int test2(B* this,int m,int n)
{
	return this->b*m*n;
}

//********************
void objPlay(A* base,int m,int n)     
{
	int temp=base->ptr->vfun(base,m,n);     
	printf("base->ptr->vfun(base,m,n): %d\n",temp);
}

//********************
void main()
{
	vir1 v1; A c1; 
	vir2 v2; B c2; 

	c1.ptr=&v1; (c1.ptr)->vfun=test1; c1.a=0;
	c2.ptr=&v2; (c2.ptr)->vfun=test2; c2.a=1;c2.b=10;

	objPlay(&c1,10,10);    // 20
	objPlay(&c2,10,10);    // 1000
}

#ifdef __cplusplus
}
#endif // __cplusplus

    2.结构体类型A中将虚表指针声明放在所有non-static变量声明的前面是实现多态的重要保证
        (1)多态发生需要3个条件:要有继承、要有虚函数重写、要有父类指针(或引用)指向子类对象
        (2)当父类指针(或引用)指向子类对象时,由于子类指针的步长比父类要长,故这过程有一次类型转换,会使子类对象丢失部分新增的non-static成员变量,但是,"结构体类型A中将虚表指针声明放在所有non-static变量声明的前面"使得用于发生多态的部分不会丢失,这保证了多态正常发生.

二、程序流程说明:
    B类对A类的继承
    1.数据:
        (1)拷贝A类的non-static数据;
            从classA.h到classB.h
            static为全局属性,故B类可以像A类一样利用它,并不需要拷贝.
        (2)修改类型定义;
            将拷贝到classB.h的结构体类型A改成B,virtualListA改成virtualListB
        (3)添加扩充的数据.
            non-static成员变量添加到结构体类型B中的末尾,虚函数指针添加到结构体类型virtualListB中的末尾
            static成员变量添加到所有non-static数据之后,并主函数所在的框架里中做特殊的初始化.(详见test.c)
    2.虚函数:重新定义和重实现虚函数.
    3.构造析构函数:重新编写.(可以通过修改原来父类的构造析构函数完成新函数编写)

    //静态成员函数和普通成员函数可以直接继承
    4.静态成员函数:不需要拷贝等任何处理.(原因和static变量不需要拷贝类似)
    5.普通成员函数:不需要拷贝等任何处理.(由于C中的类型转换机制:B类对象可以直接转换成A类,即int normFun1(A *pthis)可以传入B类型的参数, 故不需要拷贝等任何处理)

按照一中的技术结合虚表指针技术,可以完全的实现C++中的多态特性;

按照二中的继承流程,可以实现C++中的封装与继承特性.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
 

猜你喜欢

转载自blog.csdn.net/A_Pointer/article/details/81263167
今日推荐