工业强度的C++设计(第一章)

来源:互联网 发布:大型数据中心网络 编辑:程序博客网 时间:2024/04/26 23:55

1

From C to C++

 
 

Overview:

C++ is derived from C, C can also do quite a lot that C++ do, but in general C++ do in much graceful way. There are enormous potential benefits in C++ that C lacks. Consider that there are too much C++ programmers who were once C programmers, we cover some attention should be paid from C to C++. As I said, they often do the same thing, but in different ways. In this chapter we will check their difference in detail and give some advice.
 
1.1   Give up Macros
 
Macros are widely used in C, C programmers still can’t help using macros though he or she have better choice. Look at the following simple example[1]:
#include <stdio.h>
#define NUM1 3            //we will replace “3” with “3.0” later
#define NUM2 2
 
main()
{
       printf("%.2f",NUM1/NUM2);
}
 
output:  0.00
You may have known that the result is different from our expectation: we expect to get the output: 1.50 but we get 0.00 instead. Then replace “3” in the second line with “3.0”, we will get “1.50”. It is easy indeed. Really? But you should know why this phenomenon happens. The problem is that the constant defined above lacks of type declaration: what type NUM1 or NUM2 is? Is NUM1 an “int” or a “float”. ANSI C usually treats “3” as an “int”, treat “3.0” as a “float”. The compiler does an implicit type conversion for you automatically.
 
Moreover, NUM1 and NUM2 may be removed from the source file by the preprocessor, so you can’t find NUM1 or NUM2 in the symbol table, which may cause difficulty debugging a program: You may find “3” in debugger instead of NUM1, what make thing worse is that whether “3” stands for NUM1 or not (may be “3” is another constant defined by programmer such as #define NUM3 3,that is quite confusing). 
 
From the discussion above we conclude that defining a constant using a macro is dangerous: Unlike the simple program shown above, most soft wares we build are complex, you can’t reckon on the compiler’s performing exactly as you wish. We can’t predict what the result will be precisely and explicitly. There is an improvement in C++: we can use the keyword const to define a constant. Rather than writing codes above, we simply rewrite codes above as following:
 
const int NUM1 = 3;
const int NUM2 = 2;
 
Besides a the macro may be used to specify families of functions and types. In C++, we use template instead of a macro due to there are a lot features that template supports while a macro doesn’t (we will examine this features in detail in the next chapters).
 
       Though its drawbacks, it is not completely eliminated. Preprocessors still plays an important role in controlling compilation. In practice, nearly every *.h and *.cpp file use #include, #ifdef and #ifndef.
 
       In brief, Macros are almost necessary in C++. Use keyword const to define constants, inline to avoid function-calling overhead, template specifies families of functions [BJARNE].
 
1.2Use new and delete instead of malloc and free
It is evident that malloc and free are not aware of the existence of constructors and destructors (How can you expect the C language designed in 1960s to know about the C++ designed in 1980s?). Consider the example given in [LIPPMAN]:
 
To get space for an array of 10 string objects, one using malloc, the other using new:
 
string* stringArray1=static_cast<string*>(malloc(10*sizeof(string)));
string* stringArray2 = new string[10];
 
Though we have allocated memory to store 10 string objects in stringArray1, it is nearly impossible for us to initialize objects in stringArray1. In short, we allocate memory theoretically, but in practice it is useless. On the other hand, memory of stringArray2 allocated by new contains 10 initialized objects. You can visit every object as:  stringArray2[0], stringArray2[1] …
Let’s turn to free, as I said above, free knows nothing about destructors. Unfortunately there is a basic principle that every instance of Class releases its memory in the destructor. Because free is unable to invoke destructors, there is no guarantee that the memory allocated will be released properly. The default behavior is not defined; it may crash at an unknown time. As to delete, it can invoke destructor for each instance and release memory as you wish.
 
So if you would like to expected your program to crash and be fired by your boss, mix new and delete with malloc and free together. Or you can simply remember the following solution:
 
Never mix new and delete with malloc and free.


[1]  Src/chapter1/ex1_1_1.c   (All programs have been compiled using visual c++ 6.0. Because there is no room for me to upload the source code, the code is now unavailable. If you have room on the web for me or if you want to read the source code ,contact me: blue_developer@sina.com
 
原创粉丝点击