How to rewrite C++ source program into C language
[Copy link]
Since the storage space occupied by the C ++ interpreter is about 500k larger than that of the C language interpreter , it is necessary to rewrite the source program written in C ++ language into C language in order to save limited storage space, reduce costs, and improve efficiency .
The biggest difference between C ++ and C is the concept and characteristics of classes in C ++. The problem of changing C ++ to C is transformed into the problem of how to remove the classification.
There are two methods:
The first is to remove the object-oriented features in C ++, first fully understand the logic of the source code, and then rewrite it; the second is to retain some object-oriented features in C and use structures to implement class functions.
The first method is OK when there are only a few classes. However, if there are a large number of classes, it will be very time-consuming and error-prone to understand all the source code and then rewrite it. What's worse, if you encounter a large project, it is almost impossible to understand all the source code.
There are more than 140 classes in the hpijs program . At this time, the second method is needed. You can modify one class at a time without much difficulty. If there is no typo, there will be almost no mistakes, and you don’t need to understand the program logic at all. Maybe after the modification, you still have no idea about the functions that the program is going to achieve. It’s not that knowing nothing is good for everyone, but I just want to say that this method has nothing to do with the program logic itself.
The following is a preliminary discussion of some of the features of C ++ and how to implement or replace them in C :
illustrate:
Function Ixx is the implementation of the constructor of class xx .
The member functions of the original class are changed to functions prefixed with the structure name + ' _ '.
Function pointer U is the declaration of the destructor of the original class;
U + the name of the structure is the implementation of the destructor of the original class;
Fun-_+ structure name points to the member function pointer of the structure;
The above situation will not be explained in the future.
1. Class member functions and data members
Since struct does not control the access rights of its members, an additional mechanism must be added for access control, which complicates the program, so we have to give up the control of access rights.
1 ) The data members of a class can be directly converted to data members of a structure in C.
2 ) Functions need to be converted into corresponding function pointers, because function declarations and definitions are not allowed in structs . If there are modifiers such as virture and inline before the function , they must also be removed. For example, the function void funca(int a); is changed to void (*funca)(struct B *p,int a);. You can see that a pointer to struct B is added to the prototype of the function pointer . This is because the members of the class need to be operated inside the function, and the members of the structure must be specified by the pointer. In the member function of the class, there is actually an implicit this pointer pointing to itself in the parameter list .
3 ) Static members must be defined as global variables or global functions, because there cannot be static members in a structure.
2. Class constructor
When a class is instantiated, the default constructor of the class will be called. In the struct , a function pointer with the same name should be defined to point to an initialization function with constructor function. Unlike the constructor, a statement for initializing the function pointer should be added to the initialization function . When using it, malloc should be used instead of new when creating a structure variable , and the initialization function should be called manually at this time.
As shown in the following example:
Class A
{
public:
A();
~A();
void func(int a);
private:
int b;
};
A::A()
{
b=0;
}
void A :: func(int a)
{
b=a;
}
typedef struct classA A;
struct classA
{
void (*A)(struct classA *p);// constructor pointer
void (*U)(struct classA *p);// destructor pointer
void (*func)(struct classA *p,int a);
int b;
};
void fun_A(A *p)
{
p->func=classA_func; // Initialize the function pointer
}
void IA(A *p) // Constructor, the naming rule is to add I before the class name
{
fun_A(p);
p->b=0; // Part of the original constructor
}
void classA_func(A *p,int a)
{
p->b=a;
}
Where used, the following is used:
A *s=(A*)malloc(sizeof(A));
s->A=IA;
s->A(s);
3. Class destructor
The job of a class's destructor is to release the resources it holds.
In C , no matter which struct , the destructor is replaced by the function pointer U. The reason why all structs use the pointer U is based on the following circumstances:
If a subclass pointer is assigned to a base class pointer, the base class pointer does not need to consider which function name to call when it is released, but only needs to call member function U. Member function U needs to be specified in the fun_class name () function like a general member function .
The destructor of a class is called by the system, but it must be called explicitly in C. As for when to call it, you need to make an accurate judgment.
4. Class copy constructor
The main purpose of a class's copy constructor is to speed up class construction in the following situations:
1. Passed to the function as a parameter. ( additem ( Itema ))
2. As a function return value.
3. Use as a parameter when instantiating a class.
In all three cases, the system directly calls the class's copy constructor instead of the constructor.
Note: C=D ; the copy constructor will not be called. In this case, the method of overloading the '=' operator is used. ( See operator overloading for details );
Since pointers are used when defining struct variables in C , and copy constructors are not used, they are not considered for now. For the original function parameters or return values that require class variables, they must all be converted into class pointers. In the case of using parameters when instantiating a class, this can be solved by defining another constructor with parameters.
5. Inline functions and virtual functions of classes
The modifiers inline and virtual functions should be removed. The inline function body should be removed , and the inline function should be defined as a function outside. For example:
Class B
{
…
virture void funb();
inline int add()const {return a+b;};
private:
int a;
int b;
…
}
to:
typedef classB B;
struct classB
{
…
void (*funb)(struct classB *p);
int (*add)(struct classB *p);
int a;
int b;
}
void classB_funb(B *p)
{
…
}
int classB_add(B *p)
{
return p->a+p->b;
}
void fun_classB(B *p)
{
…
p->funb=classB_funb;
p->add= classB_add;
}
6. Overloading
There are two types of overloading in a class: function overloading and operator overloading:
1 ) Function overloading
The conditions for function overloading are: the function names are the same, but the number of parameters or the parameter types are different.
In this way, when calling, different functions will be called according to the parameters you input.
In C , there is no other solution except to give them different names.
2 ) Operator overloading
Operator overloading is just to meet the common habit of operator usage without causing errors.
C does not support operator overloading, but you can define a function to implement this functionality.
This is a general class modification.
VII . Others
The above are the main features and modification methods of C ++ that are the most different from C. There are also some other features, such as the use of templates, which are for the convenience of programming and code reuse. C does not have them, so I have to write multiple functions to implement them separately. In addition, the & symbol in the parameter list should be replaced with a pointer, and the default value should also be removed. When calling, be sure to write the default value.
|