Try to use const and inline without #define (from Effective C ++)

xiaoxiao2021-03-06  115

It is best known as: "Try to use compilers without pre-processes" because #define is often considered to be part of the language itself. This is one of the problems. Look at the following statement:

#define aspect_ratio 1.653

The compiler will never see the symbol name of Aspect_Ratio because it will be removed by the pre-processing program before the source code enters the compiler, so AsPect_Ratio does not join the symbol list. If the code involved in this constant is compiled, it will be aware of because the error information refers to 1.653 instead of aspect_ratio. If Aspect_Ratio is not defined in your own header file, you will be strange 1.653 where to come, even spend time tracking. This issue will also appear in the symbol debugger, because the same, the symbol name you wrote will not appear in the symbol list.

Solution to this problem is simple: do not need to preprocess macro, define a constant:

Const Double aspect_ratio = 1.653;

This method is effective. But there are two special circumstances to pay attention.

First, it will be a bit different when defining a pointer constant. Because constant definitions are typically placed in the header file (many source files will contain it), in addition to the type referred to by the pointer to be defined as consts, the pointer is often defined as const. For example, to define a CHAR *-based string pattern in the header file, you have to write twice:

Const char * const authorname = "scott meyers";

In addition, it is also very convenient to define a class (Class), only a little difference. To limit constant to the class, you must first make it a member of the class; in order to ensure that there is only one copy, it will define it as a static member:

Class GamePlayer {

Private:

Static const Int num_turns = 5; // constant ecaration

int Scores [Num_Turns]; // Use of constant

...

}

Another point, as you can see, the above statement is Num_TURNS declaration, not defined, so you must also define a static member of the class in the category implementation code file:

Const int gameplayer :: num_turns; // mandatory definition;

// Goes in class Impl.file

You don't have to worry too much. If you forget the definition, the linker will remind you.

Older compilers do not accept this grammar because it thinks that the static member of the class defines the initial value when the declaration is illegal; and only the initial integer type (eg int, bool, char, etc.) is allowed within the class. Can only be constant. In the case where the above syntax cannot be used, you can define the initial value:

Class EngineeringConstants {// THIS GoES in The Class

Private: //Header File

Static const Double fulge_factor;

...

}

// this Goes in the class mailmentation file

Const Double EngineeringConstants :: fudge_factor = 1.35;

In most cases, you just do so much. The only exception is that when your class needs to use the constant of this class, for example, the declaration of the GamePlayer :: Scores array (during the compilation process must know the size of the array). Therefore, in order to make up for the insufficient compiler of the compiler in which the intersection of the intersection of the entire class is prohibited, it can be used to solve the method called "borrowing ENUM". This technology uses the principle of using enumeration types when you need int types, so GamePlayer can also be defined like this: Class GamePlayer {

Private:

Enum {num_turns = 5} // "The Enum Hack" - Makes

// Num_turns a Symbolic Name

// for 5

Int scorers [num_turns]; // fine

}

Unless you are using the old compiler (ie, before 1995), you don't have to borrow ENUM. Of course, I know that this method is still worth it, because this code that can be traced back to the era of a long time is uncommon.

Go back to the topic of the pretreated. Another common #define directive usage is to use it to implement macros that look like a function and does not cause function calls. A typical example is the maximum value of two objects:

#define max (a, b) ((a)> (b)? (a): (b))

This statement has a lot of defects, and the light is thinking that people are distressed, even more painful than driving the highway at the peak time.

Whenever you write a macro like this, you have to remember that you have to add parentheses to each parameter when writing the body; otherwise, if you call your macro, if you use the expression, you will cause a lot of trouble. . But even if you do this, there will be a strange thing like this:

INT A = 5, b = 0;

Max ( a, b); // a value increased by 2 times

MAX ( a, b 10); // a value only increases 1 time

In this case, what happens inside the MAX depends on what is it compared! Fortunately, you don't have to endure such a stupid statement. You can use a normal function to achieve macro efficiency, plus the expected behavior and type security, which is the inline function:

Inline int Max (int A, int b) {RETURN A> B? A: B;}

However, this is not large as the above macro, because this version of MAX can only handle the int type. But the template can solve this problem very lightly:

Template

Inline Const T & Max (Const T & A, Const T & B)

{RETURN A> B? a: b;}

This template has a complete set of functions, each function takes two objects that can be converted into the same type of objects and return a reference to a large (constant) object. Because I don't know the type of T, the transfer reference can be improved when the T is returned.

By the way, check the standard library when you plan to write like MAX, first check the standard library, see if they already exist. For example, the Max saying above, you will surprise you can find a cold: max is part of the C standard library. With const and inline, you need to decrease the pretreatment, but you can't do it completely. Abandoning #include's days is still far away, # ifdef / # ifndef also plays an important role in the process of controlling compilation. Preprocessing can't retire, but you must plan to give it a long holiday.

转载请注明原文地址:https://www.9cbs.com/read-100113.html

New Post(0)