11 Frequently Asked Questions by C ++ programmers

Source: Internet
Author: User

11 Frequently Asked Questions by C ++ programmers

 

This article has been collected for a long time, but I still feel that as a collection, in such an impetuous environment on the internet, I seldom read such a long article seriously, I have time to take the Reading Notes of Objective C ++.

The original text is as follows:

 

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 standard libraries instead of updating them. 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. From a functional point of view, <iostream> contains a series of templated I/O classes. On the contrary, it only supports batch streams. In addition, the C ++ standard interface of the input/output stream has been improved in some subtle details. Therefore, it is different from the interface and execution. Finally, each group of Chengdu is declared in STL format, but each component is declared as a global one.

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 the old to maintain code consistency in order to inherit.

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, and more likely cause unexpected behavior of 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 statement 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 filling 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 source 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.

========================================================== ======================================

Reprinted statement:This article from the csdn blog, reprinted please indicate the source http://blog.csdn.net/wanfustudio/archive/2006/11/01/1360843.aspx

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.