C ++ coding considerations

Source: Internet
Author: User

The following points apply to all c ++ programmers. The reason why I say they are the most important is that you often cannot find them in C ++ books or websites. For example, the pointer to a Member is not to be mentioned in many documents, but also frequent errors, even for some advanced C ++ programmers.

The main point here is not only to explain how to write better code, but also to show what is in the language rules. Obviously, they are permanent good materials for C ++ programmers. I believe this article will help you gain a lot.
First, I will combine the questions that C ++ programmers at different levels often ask. I was surprised to find that many experienced programmers haven't realized whether the. h symbol should still appear in the standard header file.
Key Aspect 1: Or ?
Many C ++ programmers are still using Instead of using the updated standard Library. What are the differences between the two? First, five years ago, we began to oppose the use of the. h symbol in standard header files. It is not a good way to continue using outdated rules. In terms of functionality, Contains a series of templated I/O classes. It only supports batch streams. In addition, the C ++ standard interface of the input/output stream has been improved in some subtle details. Therefore, And The interface and execution are different. Finally, Each group of Chengdu is declared in STL format. However All components are declared as global.
Because of these differences, you cannot confuse these two libraries in a program. As a habit, it is generally used in new code But if you are dealing with code written in the past, you can continue to use Maintain code consistency.
Key 2: notes when passing parameters through references
When passing parameters with references, it is best to declare the references as the const type. The advantage of this is that the program cannot modify this parameter. In the following example, function f () is the reference passed:
Void F (const Int & I );
Int main ()
{
F (2);/* OK */
}
This program passes a parameter 2 to F (). At runtime, C ++ creates a temporary variable of the int type whose value is 2 and passes its reference to F (). this temporary variable and Its Reference are created and exist since F () is called until the function is returned. Is deleted immediately. Note: if we do not add the const qualifier before the reference, function f () may change the value of its parameter, which may lead to unexpected behavior in the program. So don't forget Const.
This key point also applies to user-defined objects. You can add references to temporary objects if they are of the const type:
Struct {};
Void F (const A & );
Int main ()
{
F (a (); // OK, the const reference of a temporary A is passed.
}
Key Aspect 3: comma separated expression
The comma-separated expression is inherited from C and used in the for-and while-loops. Of course, this syntax rule is considered not intuitive. First, let's take a look at what is a comma separated expression.
An expression is composed of one or more other expressions separated by commas, for example:
If (++ X, -- y, Cin. Good () // three expressions
This if condition contains three expressions separated by commas. C ++ calculates each expression, but the result of the complete comma separated expression is the value of the rightmost expression. Therefore, the value of the IF condition is true only when cin. Good () returns true. The following is another example:
Int J = 10;
Int I = 0;
While (++ I, -- J)
{
// Until J = 0, the loop ends. During the loop, I continuously auto-Increment
}
Key 4: Use the global object constructor to call the function before the program starts.
Some applications need to call other functions before the main program starts. For example, Transition Functions and registration functions must be called before the actual program runs. The simplest way is to call these functions through a global object constructor. Because global objects are constructed before the main program starts, these functions will return results before Main. For example:
Class Logger
{
Public:
Logger ()
{
Activate_log (); // Note: Call the function you need to run first in the constructor.
}
};
Logger log; // a global instance
Int main ()
{
Record * prec = read_log (); // Translator's note: Read log file data
// .. Program code
}
The Global Object log is constructed before the main () operation, and the log calls the activate_log () function (). Therefore, when main () is executed, it can read data from the log file.
Undoubtedly, memory management is the most complex and prone to bugs in C ++ programming. Directly accessing the original memory, dynamically allocating storage, and maximizing the efficiency of the C ++ command make you do your best to avoid Memory bugs.
Key 5: Avoid using pointers to functions in Complex Structures
The pointer to a function is one of the least readable syntax in C ++. Can you tell me what the following statements mean?
Void (* P [10]) (void (*)());
P is an array of 10 pointers pointing to a function that returns the void type and points to another function that does not return or operate ". This troublesome syntax is really hard to recognize, isn't it? In fact, you can simply declare functions equivalent to the preceding statements through typedef. First, use typedef to declare "pointer to a function without return or operation ":
Typedef void (* PFV )();
Then, declare "another pointer to a function that does not return and uses PFV ":
Typedef void (* pf_taking_pfv) (PFV );
Now, declare an array composed of 10 pointers above:
Pf_taking_pfv P [10];
Same effect as void (* P [10]) (void. But is it more readable!
Key 6: pointer to a member
A class has two basic types of members: function members and data members. Similarly, there are two types of pointers to members: pointers to function members and pointers to data members. It is not commonly used because classes generally do not contain public data members. They are used only to inherit the code written in C to coordinate the structure (struct) and Class (class).
Pointers to members are one of the most incomprehensible structures in C ++ syntax, but they are also the most powerful feature of C ++. It allows you to call a function member of a class without having to know the name of the function. This very agile calling tool. Similarly, you can use a pointer to a data member to check and change the data without having to know its member name.
Pointer to a data member
Although at the beginning, the syntax for pointing to the member pointer may confuse you a little bit, but you will soon find that it is actually similar to a common pointer, but it is more:: Symbol and class name. For example, define a pointer to the int type:
Int * PI;
Define a data member pointing to an int type class:
Int A: * PMI; // PMI is a member of the int type pointing to Class.
You can initialize it like this:
Class
{
Public:
Int num;
Int X;
};
Int A: * PMI = & A: num;
The code above declares an int-type num member pointing to Class A and initializes it as the address of this Num member. by adding * Before PMI, you can use and change the value of the num member of Class:
A A1, A2;
Int n = A1. * PMI; // assign a1.num to n
A1. * PMI = 5; // assign 5 to a1.num
A2. * PMI = 6; // assign 6 to 6a2. Num.
If you define a pointer to Class A, you must use the-> * operator instead of the above operation:
A * pA = new;
Int n = pa-> * PMI;
Pa-> * PMI = 5;
Pointer to a function Member
It consists of the Data Types returned by function members. The class name follows the symbol, pointer name, and function parameter list. For example, a pointer to a function member of Class A (this function returns the int type:
Class
{
Public:
Int func ();
};
INT (A: * PMF )();
The above definition means that PMF is a pointer to the function member func () of Class. in fact, this pointer is no different from a common pointer to a function, but it contains the class name and: symbol. You can call this function in any place where * PMF is used.
Func ():
PMF = & A: func;
A;
(A. * PMF) (); // call A. func ()
If you first define a pointer to an object, the above operation should be replaced by->:
A * pA = &;
(Pa-> * PMF) (); // call pa-> func ()
The pointers to function members should consider polymorphism. Therefore, when you call a virtual function member through a pointer, this call will be dynamically recycled. You cannot take the address of the constructor and destructor of a class.
Key Aspect 7. Avoid memory fragmentation
This often happens when your application leaks out of memory due to its own defects every time it runs, and you repeat your program periodically, as you can imagine, it also causes the system to crash. But how can we prevent it? First, try to use less dynamic memory. In most cases, you may use static or automatic storage or STL containers. Second, allocate as much memory as possible instead of allocating only a small amount of memory at a time. For example, allocate the memory required by an array instance at a time, instead of allocating the memory of only one array element at a time.
Key Aspect 8: delete or delete []
The programmer has an absurd saying: it is okay to use Delete instead of Delete [] to delete the array type!
For example:
Int * P = new int [10];
Delete P; // error, which should be: Delete [] P
The above program is completely incorrect. In fact, an application that uses Delete [] on a platform may not cause a system crash, but it is luck. You cannot guarantee that your application will be compiled on another compiler and run on another platform. Therefore, use Delete [].
Key 9. Optimizing member Arrangement
The size of a class can be changed as follows:
Struct
{
Bool;
Int B;
Bool C;
}; // Sizeof (A) = 12
On my computer, sizeof (a) equals 12. This result may surprise you, because the total number of members of a is 6 bytes: 1 + 4 + 1 bytes. Where did the other 6 bytes come from? The compiler inserts three Padding Bytes after each bool member to ensure that each member is arranged in 4 bytes for division. You can reduce the size of a:
Struct B
{
Bool;
Bool C;
Int B;
}; // Sizeof (B) = 8
This time, the compiler inserts only two bytes after member C. Because B occupies 4 bytes, it is naturally arranged as a word, and the size of a and c is 1 + 1 = 2, adding two bytes will arrange B in the form of two words.
Key 10: Why is it dangerous to inherit a class without virtual destructor?
A class without virtual destructor means it cannot be used as a base class. Such as STD: String, STD: complex, and STD: vector. Why is it dangerous to inherit a class without virtual destructor? When you create a class that inherits from the base class, the pointer and reference in the New Class Object actually point to the original object. Because the Destructor are not virtual functions, when you delete a class like this, C ++ will not call the Destructor chain. For example:
Class
{
Public:
~ A () // not a virtual function
{
//...
}
};
Class B: public a // error; A does not have a virtual destructor
{
Public:
~ B ()
{
//...
}
};
Int main ()
{
A * P = new B; // It looks right
Delete P; // error. The destructor of B is not called.
}
Key Aspect 11: declare Nested classes with a friend class
When you declare a nested class with a friend Meta class, put the friend meta declaration behind the nested class declaration without leading it.
Class
{
PRIVATE:
Int I;
Public:
Class B // nesting class declaration before
{
Public:
B (A & A) {a. I = 0 ;};
};
Friend Class B; // friend class declaration
};
If you place the comments declaration in front of the declared nested class, the compiler will discard the rest declaration after the peer class.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.