/*
The following code maps the C++ code for the Shape and Circle classes
to C code.
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define TRUE 1
#define FALSE 0
typedef int BOOLEAN;
/*
Error handler used to stuff dummy VTable
entries. This is covered later.
*/
void pure_virtual_called_error_handler();
/* Prototype graphics library function to draw a circle */
void glib_draw_circle (int x, int y, int radius);
typedef void (*VirtualFunctionPointer)();
/*
VTable structure used by the compiler to keep
track of the virtual functions associated with a class.
There is one instance of a VTable for every class
containing virtual functions. All instances of
a given class point to the same VTable.
*/
typedef struct VTable
{ /*
d and i fields are used when multiple inheritance and virtual
base classes are involved. We will be ignoring them for this
discussion.
*/
int d;
int i;
/*
A function pointer to the virtual function to be called is stored here.
*/
VirtualFunctionPointer pFunc;
}VTable;
/*
The Shape class maps into the Shape structure in C. All
the member variables present in the class are included
as structure elements. Since Shape contains a virtual
function, a pointer to the VTable has also been added.
*/
typedef struct Shape
{
int m_x;
int m_y;
/*
The C++ compiler inserts an extra pointer to a vtable which
will keep a function pointer to the virtual function that
should be called.
*/
VTable *pVTable;
}Shape;
/*
Function prototypes that correspond to the C++ methods
for the Shape class,
*/
Shape *Shape_Constructor(Shape *this_ptr, int x, int y);
void Shape_Destructor(Shape *this_ptr, BOOLEAN dynamic);
void Shape_MoveTo(Shape *this_ptr, int newX, int newY);
void Shape_Erase(Shape *this_ptr);
/*
The Shape vtable array contains entries for Draw and MoveTo
virtual functions. Notice that there is no entry for Erase,
as it is not virtual. Also, the first two fields for every
vtable entry are zero, these fields might have non zero
values with multiple inheritance, virtual base classes
A third entry has also been defined for the virtual destructor
*/
VTable VTableArrayForShape[] =
{ /*
Vtable entry virtual function Draw.
Since Draw is pure virtual, this entry
should never be invoked, so call error handler
*/
{ 0, 0, (VirtualFunctionPointer) pure_virtual_called_error_handler},
/*
This vtable entry invokes the base class's
MoveTo method.
*/
{ 0, 0, (VirtualFunctionPointer)Shape_MoveTo },
/* Entry for the virtual destructor */
{ 0, 0, (VirtualFunctionPointer)Shape_Destructor }
};
/*
The struct Circle maps to the Circle class in the C++ code.
The layout of the structure is:
- Member variables inherited from the the base class Shape.
- Vtable pointer for the class.
- Member variables added by the inheriting class Circle.
*/
typedef struct Circle
{
/* Fields inherited from Shape */
int m_x;
int m_y;
VTable *pVTable;
/* Fields added by Circle */
int m_radius;
}Circle;
/*
Function prototypes for methods in the Circle class.
*/
Circle *Circle_Constructor(Circle *this_ptr, int x, int y, int radius);
void Circle_Draw(Circle *this_ptr);
void Circle_Destructor(Circle *this_ptr, BOOLEAN dynamic);
/* Vtable array for Circle */
VTable VTableArrayForCircle[] =
{ /*
Vtable entry virtual function Draw.
Circle_Draw method will be invoked when Shape's
Draw method is invoked
*/
{ 0, 0, (VirtualFunctionPointer) Circle_Draw },
/*
This vtable entry invokes the base class's
MoveTo method.
*/
{ 0, 0, (VirtualFunctionPointer) Shape_MoveTo },
/* Entry for the virtual destructor */
{ 0, 0, (VirtualFunctionPointer) Circle_Destructor }
};
Shape *Shape_Constructor(Shape *this_ptr, int x, int y)
{
/* Check if memory has been allocated for struct Shape. */
if (this_ptr == NULL)
{
/* Allocate memory of size Shape. */
this_ptr = (Shape *) malloc(sizeof(Shape));
}
/*
Once the memory has been allocated for Shape,
initialise members of Shape.
*/
if (this_ptr)
{ /* Initialize the VTable pointer to point to shape */
this_ptr->pVTable = VTableArrayForShape;
this_ptr->m_x = x;
this_ptr->m_y = y;
}
return this_ptr;
}
void Shape_Destructor(Shape *this_ptr, BOOLEAN dynamic)
{ /*
Restore the VTable to that for Shape. This is
required so that the destructor does not invoke
a virtual function defined by a inheriting class.
(The base class destructor is invoked after inheriting
class actions have been completed. Thus it is not
safe to invoke the ineriting class methods from the
base class destructor)
*/
this_ptr->pVTable = VTableArrayForShape;
/*
If the memory was dynamically allocated
for Shape, explicitly free it.
*/
if (dynamic)
{
free(this_ptr);
}
}
void Shape_MoveTo(Shape *this_ptr, int newX, int newY)
{
this_ptr->m_x = newX;
this_ptr->m_y = newY;
//printf("MoveTo X:%d Y:%d \n",newX,newY);
}
void Shape_Erase(Shape *this_ptr)
{
this_ptr->m_x = 0;
this_ptr->m_y = 0;
//printf("Erase\n");
}
Circle *Circle_Constructor(Circle *this_ptr, int x, int y, int radius)
{
/* Check if memory has been allocated for struct Circle. */
if (this_ptr == NULL)
{
/* Allocate memory of size Circle. */
this_ptr = (Circle *) malloc(sizeof(Circle));
}
/*
Once the memory has been allocated for Circle,
initialise members of Circle.
*/
if (this_ptr)
{ /* Invoking the base class constructor */
Shape_Constructor((Shape *)this_ptr, x, y);
this_ptr->pVTable = VTableArrayForCircle;
this_ptr->m_radius = radius;
}
return this_ptr;
}
void Circle_Destructor(Circle *this_ptr, BOOLEAN dynamic)
{
/* Restore the VTable to that for Circle */
this_ptr->pVTable = VTableArrayForCircle;
/*
Invoke the base class destructor after ineriting class
destructor actions have been completed. Also note that
that the dynamic flag is set to false so that the shape
destructor does not free any memory.
*/
Shape_Destructor((Shape *) this_ptr, FALSE);
/*
If the memory was dynamically allocated
for Circle, explicitly free it.
*/
if (dynamic)
{
free(this_ptr);
}
}
void Circle_Draw(Circle *this_ptr)
{
glib_draw_circle(this_ptr->m_x, this_ptr->m_y, this_ptr->m_radius);
}
void pure_virtual_called_error_handler()
{
}
void glib_draw_circle (int x, int y, int radius)
{
//printf("draw circle x:%d y:%d radius:%d \n",x,y,radius);
}
void call()
{
/*
Dynamically allocate memory by passing NULL in this arguement.
Also initialse members of struct pointed to by pShape.
*/
Shape *pShape = NULL;
/* Define a local variable aCircle of type struct Circle. */
Circle aCircle;
pShape = (Shape *) Circle_Constructor(NULL, 50, 100, 25);
/* Initialise members of struct variable aCircle. */
Circle_Constructor(&aCircle, 5, 5, 2);
/*
Virtual function Draw is called for the shape pointer. The compiler
has allocated 0 offset array entry to the Draw virtual function.
This code corresponds to "pShape->Draw();"
*/
(pShape->pVTable[0].pFunc)(pShape);
/*
Virtual function MoveTo is called for the shape pointer. The compiler
has allocared 1 offset array entry to the MoveTo virtual function.
This code corresponds to "pShape->MoveTo(100, 100);"
*/
(pShape->pVTable[1].pFunc)(pShape, 100, 100);
/*
The following code represents the Erase method. This method
没有合适的资源?快使用搜索试试~ 我知道了~
C++转C代码及效率比较
共3个文件
c:2个
cpp:1个
需积分: 49 9 下载量 18 浏览量
2011-11-02
19:23:35
上传
评论 1
收藏 4KB RAR 举报
温馨提示
C++转C代码的例子,及代码效率的比较。This section presents the C++ code for a typical virtual function invocation scenario. This is then compared to the equivalent C code. 本篇博客 http://www.cnblogs.com/mlj318/archive/2011/11/02/2233255.html
资源推荐
资源详情
资源评论
收起资源包目录
C++vsC.rar (3个子文件)
C++vsC
function_poninter.c 261B
Circle_C.c 10KB
Circle_C++.cpp 3KB
共 3 条
- 1
资源评论
mlj318
- 粉丝: 19
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功