Introduction to objective Modern C ++

Source: Internet
Author: User

Introduction to objective Modern C ++

The translation was officially started at 10:31:06, January 1, January 9, 2016, Beijing time. The level is limited. If you think it is inappropriate, please criticize and correct it. Now, let's start our translation tour of objective Modern C ++. First posture-Introduction

Introduction
If you were an expert C ++ engineer and thought the same way as when I first came into contact with C ++ 11: "Yes, I understand, C ++ 11 is nothing more than C ++ ". However, as you learn more about the language after the revision, you will be shocked by its great changes. Automatic type inference, range-based for loop, lambda expressions, and right-value reference change the appearance of C ++, not to mention the new concurrency features. There are also changes that conform to the language characteristics and habits! 0 and typedef keywords are eliminated. Instead, nullptr indicates NULL pointer and alias declaration (alias declaration ). Enumeration has a scope, and smart pointers become more perfect built-in types. Moving objects are often more reliable than copying objects. Therefore, C ++ 11 has many things worth learning.

The passing of C ++ 14 does not make these simple.

Therefore, there are many areas to learn. More importantly, how to use these new features efficiently. If you need the basic syntax and semantics of C ++ 11, the total amount of resources is rich, but if you are looking for instructions on how to write the correct and effective, this search is very challenging when you can maintain code information. This is the reason for this book. This is not a special description of the features of C ++ 11 and C ++ 14, but shows you how to effectively apply C ++ 11.

The information in this book is divided into one, which is calledTerms. Want to understand the type inference of variables? Or do you want to determine when or when to use auto to declare variables? Are you interested in why const member functions should be thread-safe? How to Use std: unique_ptr to implement pimpl? Why should you avoid the default variable capture format when using lambda expressions? Or the difference between std: atomic and volatile (how to use them correctly )? You can find the answers to these questions in the book. In addition, these answers are platform independent and consistent with the standard. This is a portable book about C ++.

Every clause is a guideline, not a guideline, because there are exceptions to the guidelines. The most important part of each clause is not the suggestions it puts forward, but the principles and thinking processes behind these suggestions. Once you have read this book, it is up to you to decide whether to ignore or apply the guidance in these terms in your project environment. The true purpose of this book is not to tell you what to do or avoid, but to convey a deeper understanding of how C ++ 11 and C ++ 14 work.

Terms and habits
To ensure that we understand each other, it is important to reach an agreement in some terms. C ++ has four standards. The naming rules are the years used by the ISO standard, C ++ 98, C ++ 03, C ++ 11, and C ++ 14. C ++ 98 and C ++ 03 only have some subtle technical details, so in this book, I call both C ++ 98.

When I mention C ++ 98, I only mean the C ++ language version. When I mention C ++ 11, I mean C ++ 11 and C ++ 14, because C ++ 14 is an effective superset of C ++ 11. When I write C ++ 14, I specifically refer to C ++ 14. If I simply mention C ++, it belongs to all language versions. Therefore, I may say that C ++ attaches great importance to efficiency (this refers to all C ++ versions ), C ++ 98 lacks support for concurrency (only C ++ 98 ), C ++ 11 supports lambda expressions (C ++ 11 and C ++ 14 ), C ++ 14 provides a more general derivation of function return types (referring to C ++ 14 only ).

The most popular feature of C ++ 11 is probably mobile semantics. The basis of mobile semantics is thatLeftOrRight Value. Because the right value implies that the object is eligible for the moving operation, the left value is usually not. In terms of concept (though not always in practice), the right value should correspond to an anonymous Temporary Variable returned from the function, while the left value should correspond to an object that you can reference, either through a pointer, it can also be referenced.

The effective way to determine whether an expression is left is to see if you can get its address. If you can, it is usually a left value. If you cannot, it is usually a right value. A good feature of this method is that it helps you remember that the type of an expression is irrelevant to whether the expression represents a left value or a right value. For a type T, you can obtain both the left Value Type of T and the right value type of T. This is very important, especially when you process a reference parameter of the right value, this is because the parameter itself is a left value.

class Widget { public:   Widget(Widget&& rhs);    // rhs is an lvalue, though it has  ....                     //an rvalue reference type     }; 

Here, the address for getting the rhs parameter in the mobile constructor of widgt is completely legal, so rhs is a left value, although its type is a reference to the right value (similar reasoning, all parameters are left values ).

This code shows a lot of conventions that I usually follow:

? The class name is widget, which is used to represent any user-defined type. I will use widgets without declaration, except in some cases, I need to display the special details of the class.

? I name the parameter rhs, which represents right-hand side. This is the operation I use to move (such as mobile construction, mobile assignment) and copy (such as copy construction and copy assignment) although I use binary operators, rhs is usually used as the name of the right side parameter.

Matrix operator+(const Matrix& lhs,const Matrix& rhs);

I hope this doesn't surprise you. lhs stands for left-hand side.

? I highlighted some of the code or comments to focus your attention on it. In the code above, I highlighted the rhs and comments, note that rhs is a left value.

? I use "…" To imply that there will be other code, here the narrow ellipsis and wide ellipsis ("…") There is a difference between them. The wide ellipsis is used as a variable-length template in C ++ 11, which sounds a bit confusing, but it is not, for example

template
  
                   // these are C++  void processVals(const Ts&... params)   // source code {                                       // ellipses 28   …                                     // this means "some                                         // code goes here"}  
  

The processVals Declaration shows that I used typename when declaring template parameters, which is just my personal preference. Class is also applicable here. When I show some code references from the C ++ standard, I will use class to declare the parameters of the template, because this is done in the standard.

When an object is initialized with another object of the same type, this new object is considered a copy of the original object, even if this copy is created through a mobile structure, unfortunately, no technology in C ++ can distinguish whether an object is created through a copy structure or a mobile structure.

void someFunc(Widget w);        // someFunc's parameter w                                                                 // is passed by value Widget wid;                     // wid is some Widget someFunc(wid);                  // in this call to someFunc,                                                                  // w is a copy of wid that's                                                                 // created via copy construction  someFunc(std::move(wid));       // in this call to SomeFunc,                                                                 // w is a copy of wid that's                                                                 // created via move construction

The copy of the right value is usually constructed by moving, and the copy of the Left value is usually constructed by copying. It implies that if you only know that an object is a copy of another object, you cannot know the cost of constructing this copy. For example, in the code above, when you do not know whether it is a left value or a right value passed to the parameter w of someFunc, you don't know the cost of creating parameter w (you also need to know the cost of copying constructor and building a widget ).

In a function call, the calling expression is the real parameter (argument) of the function. These parameters are used to instantiate the parameter (parameters) of the function ). In the first example, the real parameter is wid, and in the second example, the real parameter is std: move (wid ). In the two examples, both the form parameters are w, and the difference between the form parameters and the real parameters is very important. Because the parameters are left values, but the real parameters and instantiation of these real parameters may be left or right values, this is related to the perfect forwarding process. Perfect forwarding refers to passing parameters to the second function called in the function, the left and right values of the original parameters are retained (more details about perfect forwarding will be discussed in Clause 32 ).

Well-designed functions are exception-safe, which means they provide at least the most basic exception Security guarantee (that is, basic guarantee ). This function ensures that, even if an exception occurs, the program's invariant remains complete (that is, no data structure is damaged) and no resources are leaked, the functions that provide strong exception security assurance (that is, strong guarantee) Assure the caller that if an exception is generated, the state of the program is the same as before the call. As explained in Clause 16, the functions in the C ++ 98 Standard class Library provide strong guarantee for the mobile semantics of the C ++ 11 Standard class Library (C ++ 98 Standard Library functions offering the strong guarantee constrain the applicability of move semantics in the C ++ 11 Standard Library .).

I use the term callable entity to describe anything that can call the same syntax as calling a non-member function, such as the syntax "functionName (arguments)", function, function pointer. All function objects are callable entities ). Function objects created using lambda expressions are called closures. It is seldom necessary to distinguish a lambda expression from the closures they create, so I call them all lambdas.

Similarly, I almost do not distinguish between a function template (that is, the template that generates the function) and a template function (that is, the function instantiated from the template). The same is true for class templates and template classes.

Many things in C ++ can be declared and defined. The Declaration gives its name, but does not give too many details, such as its storage space and how it is implemented.

extern int x;                       // object declaration class Widget;                       // class declaration int func(const Widget& w);          // function declaration  enum class Color;                   // scoped enum declaration                                                                          // (see Item 10)

The definition provides its storage space and its implementation details.

class Widget {                      // class definition   … }; int func(const Widget& w) { return w.size(); }                // function definition enum class Color { Yellow, Red, Blue };              // scoped enum definition

Definitions also include declarations, so unless something is important as a definition, I generally prefer to use declarations.

The new C ++ Standard retains the validity of the original code written under the old standard, but the Standards Board occasionally discards some of the features (deprecates. This warning indicates that a feature may be removed from future standards, and you should avoid using these rejected features (the reason for rejection is that the new features usually provide the same functionality, but it has fewer restrictions and disadvantages). For example, std: auto_ptr is denied in C ++ 11, because std: unique_ptr provides the same function and performs better.

Sometimes, the standard will say that the result of an operation is undefined (undefined behavior), which means that the behavior at the runtime is unpredictable. Without a doubt, you want to avoid such uncertainty, undefined behaviors include the use of parentheses ([]), which are labeled as exceeding the std: vector boundary. This resolves the reference of an uninstantiated iterator, or it involves data competition (for example, there are more than two threads, at least one is the writer and accesses one memory unit at the same time ).

In the source code comments, I sometimes abbreviated construct as ctor and destructor as dtor.

Report Bugs and Improvement Suggestions
I try my best to make this book full of clear, specific, and useful information, but there are certainly some ways to make it better. If you have found any form of errors (technical, explanatory, syntactic, typographical, etc.), or you have suggestions for improving this book, please send an email to my mailbox[Email protected]. The new printing gives me the opportunity to revise the valid tive Modern C ++, but I cannot solve the problem I don't know.

Note: Pimpl Idiom can be used to reduce compilation dependencies between files.

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.