18 key notes for C ++ Primer Plus 6th, primerplus

Source: Internet
Author: User

18 key notes for C ++ Primer Plus 6th, primerplus

The following are the notes I have taken after reading C ++ Primer Plus version 6th, which can be used as a memorandum for future review.

Note Section
  1. Why is the const of C ++ better than that of C # define?

    First, it can explicitly specify the type and has the type check function.
    Second, you can use the scope rules of C ++ to restrict the definition to a specific function or file.
    Third, you can use const for more complex types, such as arrays and structures.

    Const also exists in C language. The difference between const and const in C ++ is:One is that the scope rules are different; the other is that the const value can be used in C ++ to declare the array length.

  2. You cannot simply assign Integers to pointers, as shown below:

    int *ptr;ptr = 0xB8000000;  // type mismatch

    Here, the left side points to the int pointer, so you can assign it to the address, but the right side is an integer. You may know that 0xB8000000 is the offset of the video memory combination segment in the old-fashioned computer system, but this statement does not tell the program that this number is an address. Prior to the release of the C99 standard, the C language allows assignment. However, C ++ imposes more strict requirements on type consistency. The Compiler displays an error message, and the announcement type does not match. To use numeric values as addresses, convert numbers to appropriate address types by force type conversion:

    int *ptr;ptr = (int *) 0xB8000000;  // type now match

    In this way, both sides of the value assignment statement are integers, so the value assignment is valid.
    Note that pt is the address of the int value and does not mean that the pt Type is int. For example, in some platforms, the int type is a 2-byte value, and the address is a 4-byte value.

  3. Why is prefix ++/-- more efficient than suffix ++?

    This does not seem to be a problem for built-in types and contemporary compilers. However, C ++ allows you to define these operators for classes. In this case, you define a prefix function: add the value to 1 and then return the result; however, the suffix version first copies a copy, adds it to 1, and then returns the copied copy. Therefore, for classes, prefix versions are more efficient than suffix versions.
    In short, there is no difference in the format used for built-in types, but for user-defined types, if there are user-defined increment and decrement operators, the prefix format is more efficient.

  4. Comma Operator
    So far, the most common use of the comma operator is to put two or more expressions into a for loop expression. The comma operator has the following features:

    • It ensures that the first expression is calculated first, and then the second expression is calculated;
      I = 20, j = 2 * I; // I set to 20, then j set to 40
    • The value of the comma expression is the value of the second part. For example, the value of the above expression is 40.
    • Among all operators, the comma operator has the lowest priority. For example:
      Cats = 17,240;
      Explained me:
      (Cats = 17), 240;
      That is to say, setting cats to 17 does not work for the subsequent 240. If it is cats = (17,240); then cats is 240.
  5. Useful Character Library cctype
    Inherited from the C language, the old format is ctype. h, commonly used:

  6. Selection of values in the quick rank:
    Set each of the five elements to the median value. Find the value in n/5 values as the partition of partition.
    Why * not every 3 groups? Ensure that there are at least 3n/10 elements on the right of the operator, which is the worst O (n ).

  7. C ++ storage solutions: three types of C ++ and four types of C ++ 11
    The difference between these solutions is the time the data is retained in the memory.

    Automatic storage persistence: The storage of variables (including function parameters) declared in the function definition is always automatic. They are created when the program starts to execute the function or code block to which they belong. When the function or code block is executed, the memory they use is released. C ++ has two types of variables that are continuously stored as automatic variables.
    Static storage persistence: The storage persistence of variables defined outside Function Definition and variables defined using the keyword static is static. They exist throughout the entire process of the program. C ++ has three types of static variables.
    Thread storage continuity (C ++ 11): Currently, multi-core processors are common. These CPUs can process multiple execution tasks at the same time. This allows the program to place computing in different threads that can be processed in parallel. If the variable is declared using the keyword thread_local, its life cycle is as long as the thread to which it belongs. This book does not discuss parallel programming.
    Dynamic storage persistence: The memory allocated with the new operator will exist until the delete operator is used to release the memory or the program ends. This kind of memory storage is dynamic and sometimes called free store or heap ).

  8. Notes for writing the string class by yourself:

    • Record the number of existing objects object_count
      Do not initialize static member variables in class declarations (header files) because they describe how to allocate memory, but do not allocate memory. For static class members, separate statements can be used for initialization outside the class declaration, because static class members are stored separately, rather than the object components. Note that the initialization statement specifies the int type (indispensable) and uses the scope operator, but does not use the keyword static.
      Initialization is performed in the method file rather than in the class declaration file. This is because the class declaration is located in the header file and may be contained multiple times. If static members are initialized in the header file, multiple copies of the initialization statement will appear, causing an error.
      An exception that Cannot initialize static members in the class declaration is that the static data member is an integer or enumeration type const. That is, if the static data member is of the integer or enumeration type, it can be initialized in the class declaration.
    • Note that the copy constructor and the value assignment operator are overwritten. The prototype of the value assignment operator is:
      Class_name & Class_name: operator = (const Class_name &);
      It accepts and returns a reference to a class object, which is intended to be used in tandem.
  9. When to call the copy (copy) constructor:

    StringBad ditto (motto);   StringBad metoo = motto; StringBad also = StringBad(motto); StringBad * pStringBad = new StringBad (motto);

    In method 4 above, StringBad (const StringBad &) will be called &)

    • The two declarations in the middle may use the copy constructor to directly create metoo and also objects, or use the copy constructor to generate a temporary object, then, the contents of the temporary object are assigned to metoo and also, depending on the specific implementation. The last declaration uses modemto Initialize an anonymous object and assigns the address of the new object to the pStringBad pointer.
    • Every time a program generates an object copy, the compiler uses the copy constructor. Specifically, when a function transmits an object by value or the function returns an object, the copy constructor is used. Remember, passing by value means creating a copy of the original variable.
    • When the compiler generates a temporary object, it also uses the copy constructor. For example, when three Vector objects are added, the compiler may generate a temporary Vector object to save the intermediate results.
    • In addition, String sailor = sports; equivalent to String sailor = (String) sports; therefore, the copy constructor is called.
  10. When to call the value assignment operator:

    • SetExisting objectWhen assigned to another object, the overloaded value assignment operator is called.
    • When initializing an object, the value assignment operator is not always used:
      StringBad metoo=knot;   // use copy constructor, possibly assignment, too
      Here, metoo is a newly created object and is initialized as the knot value. Therefore, a value assignment constructor is used. However, as mentioned above, this statement may be processed in two steps during implementation: use the copy constructor to create a temporary object, then, the value of the temporary object is copied to the new object through the value assignment operator. This means that the initialization always calls the copy constructor, And the = operator may also call the value assignment constructor.

    Similar to the copy constructor, the implicit implementation of the value assignment operator also copies members one by one. If the member itself is a class object, the program will use the value assignment operator defined for this class to copy the member, but the static data member is not affected.

  11. The differences between the value assignment operator and the copy constructor are as follows:

    • Because the target object may reference previously allocated data, the function should use delete [] to release the data.
    • The function should avoid assigning objects to itself; otherwise, the release memory operation may delete the object content before assigning values to the objects again.
    • The function returns a reference pointing to the called object (which is convenient for concatenation), but the copy constructor does not return a value.

    The following code describes how to compile a value assignment operator for the StringBad class:

    StringBad & StringBad::operator=(const StringBad & st){ if(this == & st)    return * this; delete [] str; len = st.len; str = new char [len + 1]; strcpy(str,st.str); return *this;}

    The code first checks self-replication. this is done by checking whether the address (& s) on the right of the value assignment operator is the same as the address of the receiving object (this). If it is the same, the program returns * this and ends.
    If different, release the memory pointed to by str, because the address of a new string will be assigned to str later. If the delete operator is not used first, the above string will be kept in the memory. Because the program no longer contains pointers to strings, the memory is wasted once.
    The next operation is similar to the copy constructor, that is, allocate enough memory for the new string, and then copy the string.
    The value assignment operation does not create new objects, so you do not need to adjust the value of the static data member num_strings.

  12. It is best to declare the heavy-duty operator as a friend.
    For example, using a comparison function as a friend can help you compare a String object with a regular C String. For example, if answer is a String object, the following code:
    If ("love" = answer)
    Will be converted:
    If (operator = ("love", answer ))
    The compiler then converts the code:
    If (operator = (String ("love"), answer ))
    This matches the prototype.

  13. Note the following when using brackets to access the string class:
    (1) Why is the returned value of the overload [] a char instead of a char?
    (2) why two [] versions are reloaded, and the other is the const version?

    Answer (1 ):
    Declare the return class as char & to give the limit value to a specific element. For example, you can write the following code:
    String means ("might ");
    Means [9] = 'R ';
    The second statement will be converted into an overloaded operator function call:
    Means. operator [] [0] = 'R ';
    Here, we return the return value of r callback to the method, and the function returns a reference pointing to means. str [0]. Therefore, the above Code is equivalent to the following code:
    Means. str [0] = 'R ';
    The last line of the Code accesses private data, but since operator is a class method, it can modify the array content. The final result is that "might" is changed to "right ".

    Answer (2 ):
    Suppose there are the following constant objects:
    Const String answer ("futile ");
    If only the operator definition is available, the following code will fail:
    Cout <answer [1]; // compile-time error
    The reason is that answer is a constant, and the above method cannot ensure that data is not modified (in fact, sometimes the work of this method is to modify data, so it cannot be ensured that data is not modified ).
    However, in the case of overload, C ++ will differentiate the feature labels of constants and non-constant functions. Therefore, it can provide another operator version that is only used by the const String object:
    // For use with const String objects
    Const char & string: operator const {
    Return str [I];
    }
    With the above definition, you can read/write regular String objects. For a const Siring object, you can only read its data.

  14. Static member functions cannot be added with the static keyword when they are defined outside the class Declaration. They are the same as static member variables.

  15. There are two ways to implement the has-a relationship:

    • Combination (or inclusion) method. This is what we usually use.
    • C ++ has another way to implement the has-a relationship-private inheritance. Using private inheritance, both the public and protected members of the base class are called Private Members of the derived class. This means that the base class methods will not be called part of the derived object public interface, but they can be used in the member functions of the derived class. Using Public inheritance, the public methods of the base class are called the Public methods of the derived class. In short, the derived class inherits the interface of the base class: This is part of the is-a relationship. Private inheritance is used. The public method of the base class is called the private method of the derived class, that is, the derived class does not inherit the interface of the base class. As you can see from the contained object, this incomplete inheritance is part of the has-a relationship.
      If private inheritance is used, classes are inherited. For example, if the Student class is derived from the String class, the latter has a String class component that can be used to save strings. In addition, the Student method can use the String method class to access the String component.

      The object is added to the class as a named member object, while the private inheritance adds the object to the class as an unnamed inherited object. We use term sub-objects to represent the same inherited or added objects.
      Therefore,Private inheritance provides the same features as include: Get the implementation, but do not get the interface. Therefore, private inheritance can also be used to implement the has-a relationship..

    • Use include or private inheritance?
      Since we can use both include and private inheritance to establish the has-a relationship, what method should we use?Most C ++ programmers tend to use inclusion.

      • First, it is easy to understand. The class declaration contains explicit named objects that indicate the classes to be included. The code can reference these objects by name, and using inheritance will make the relationship more abstract.
      • Second, inheritance will cause many problems, especially when inheriting from multiple base classes, many problems may have to be dealt with, such as an independent base class that contains methods of the same name or an independent base class of a common ancestor.
        In short, using inclusion is unlikely to cause such troubles.
      • In addition, it can contain multiple similar sub-objects. If a class requires three string objects, it can contain three independent string members. Inheritance can only use one such object (it is difficult to distinguish between objects without names ).

      However, private inheritance provides more features than include. For example, if a class contains a protected member (which can be a data member or a member function), such a member is fully available in the derived class, however, it is unavailable outside the inheritance hierarchy. If you use a combination to include such classes in another class, the latter will not be a derived class, but will be located outside the inheritance hierarchy, so you cannot access protected members. However, the inherited class will be a derived class, so it can access the protected member.
      Another case where private inheritance needs to be used is to redefine the callback function. A derived class can be used to redefine a virtual function, but its class cannot. If private inheritance is used, the redefined function can only be used in the class, rather than the public one.

    • In general, contain should be used to establish the has-a relationship. If the new class needs to access the protection members of the original class, or the virtual number needs to be redefined, private inheritance should be used.
  16. Protection inheritance
    Protection inheritance is a variant of private inheritance, and protection inheritance uses the keyword protected when listing the base classes;

    class Student : protected std::string,                protected std::valarray<double>{...}

    When using protected inheritance, both the public and protected members of the base class will become the protected members of the derived class. Like private inheritance, the base class interface is also available in the derived class, however, it is unavailable beyond the hierarchy of inheritance.When a derived class is derived from another class, private Inheritance and Protection inheritance
    The main difference is displayed. When private inheritance is used, the third generation will not be able to use the interface of the base class, because the common methods of the base class will become private methods in the derived class; when the inheritance is protected, the public methods of the base classes will be programming in the second generation. Therefore, the third generation derived classes can use them.

    The following table summarizes public, private, and protected inheritance. Implicit upward conversion means that you can direct a base class pointer or reference to a derived class object without explicit type conversion.

  17. Smart pointer related
    For more information, see: Simple Analysis of C ++ smart pointers.

  18. Container types in C ++:
    • Sequential container (7)
      • Vector: Provides automatic memory management (using the Memory Manager allocator, which is common in STL). It can dynamically change the object length and provide random access. The time for adding and deleting elements at the end is constant, but linear time is used in the header or in the middle.
      • Deque: Double-ended queue, which supports random access. Similar to vector, the main difference is,The time for inserting and deleting elements from the beginning of the deque object is also constant. Therefore, if most operations occur at the beginning and end of the sequence, deque data structure should be considered.To realize that the time for executing insert and delete operations on both ends of deque is constant time, the design of deque object is more complex than that of vector. Therefore, although both provide random access to elements and linear time insertion and deletion operations in the middle of the sequence, the vector container performs these operations more quickly.
      • List: Bidirectional linked list (Cyclic ). The purpose is to achieve rapid insertion and deletion.
      • Forward_list (C ++ 11): Implements a single-chain table and cannot be reversed. Compared with list, forward_list is simpler and more compact, but has fewer functions.
      • Queue: Is an adapter class. The queue template allows the underlying class (deque by default) to display typical queue interfaces. The queue template has more restrictions than deque. It not only does not allow random access to queue elements, but even does not allow traversal of queues. Like a queue, an element can only be added to the end of a team, deleted from the first of the team, checked for the value of the first and end of the team, checked for the number of elements, and checked for the test queue being empty.
      • Priority_queue: It is another adapter class that supports the same operations as queue.
        The priority_queue template class is another adapter class that supports the same operations as queue.The main difference between the two is that in priority_queue, the largest element is moved to the first of the pair. The internal difference is that the default underlying class is vector. You can modify the comparison method to determine which element is placed at the beginning of the team.To provide an optional constructor parameter:
        Priority_queue <int> pq1; // default versionpriority_queue <int> pg2 (greater <int> ); // use greater <int> to ordergreater <> is a predefined function object.
      • StackSimilar to queue, stack is also an adapter class that provides a typical stack interface for underlying classes (vector by default.
    • Associated container
      • Four TypesOrderedAssociated containers: set, multiset, map, and multimap. The underlying layer is based on the tree structure.
      • Four additional types are added for C ++ 11.UnorderedAssociated containers: unordered_set, unordered_multiset, unordered_map, and unordered_multimap. The underlying layer is based on hash.

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.