C++11 also adds a number of useful features, such as:
1. Delegate Constructors
If a class contains many constructors, these constructors have some duplication, such as:
Class A{public: A () {}; A (int a) { a_ = A; }; A (int a, int b) { a_ = A; B_ = b; }; A (int a, int b, double c) { A_ = A; B_ = b; C_ = c; }; Private: int a_; int b_; Double c_;}
The three constructors of Class A are duplicated, with the C++11 delegate constructor, which allows you to write the same content again without having to use each constructor:
Class A{public: a (int a) { a_ = A; } A (int a, int b): A (a) { b_ = b; } A (int a, int b, double c): A (A, b) { c_ = c; } Private: int a_; int b_; Double c_;}
It is important to note that if you use a delegate constructor, you cannot use class member initialization , such as:
Class A{public: a (int a): A_ (a) {};//Use class member initialization alone, can be a (int a, int b): A (a), b_ (b) {};//Use both delegate constructors and class member initialization, Error! Private: int a_; int b_;}
2. Inheritance Constructors
If a derived class inherits from a base class, if its constructor wants to use the same constructor as the base class, if the constructor has more than one, write multiple constructors in the derived class, each constructed with a base class, as follows:
Class Base{public: Base (int a); Base (int A, int b); Base (int A, int b, double c); ~base ();}; Class Derived{public: Derived (int a): Base (a) {}; Derived (int A, int b): Base (A, b) {}; Derived (int A, int b, double c): Base (A, B, c) {};};
In c++11, you can use an inheritance constructor to simplify this operation:
Class Base{public: Base (int a); Base (int A, int b); Base (int A, int b, double c); ~base ();}; Class Derived{public: Using base::base;//Declaration Use base class constructor //Use inheritance constructor, do not repeat};
More than just constructors, you can declare any other function to use a function in a base class in a derived class:
struct base{ void Func () { cout << "call in Base" << Endl; }}; struct derived:base{ void Func (int a) { cout << "call in Derived" << Endl; }}; int main () { Derived D; D.func (); Compile error because the Func () function is not declared in the derived class, only the func (int) function return 0;};/ /in c++11, use the inheritance function to change to the following form: struct derived:base{ void Func (int a) { cout << "call in Derived" << Endl; }};
3. The original literal
The original literal can directly represent the actual meaning of the string, because some strings have special characters, such as in an escaped string, which we tend to specialize in. such as Windows path name: D:\A\B\test.txt "
In c++11, use R "xx (string) xx" To get the string form of the strings in parentheses, without the need for additional characters such as escape characters, such as:
String a = R "(D:\A\B\test.txt)"
Note that R "xxx (raw string) xxx", where the original string must be enclosed in parentheses (), the parentheses before and after the addition of other strings, the added string is ignored, and the addition of the string must appear on both sides of the parentheses.
String str = r "Test (D:\A\B\test.txt)";//error, test only appears on one side of string str = r "Test (D:\A\B\test.txt) TT";//error, the left and right sides of the string are different string str = r "Test (D:\A\B\test.txt) test"//ok string str = r "(D:\A\B\test.txt)"//ok
4. Final or override keywords
The final keyword is added in c++11 to restrict a class from being inherited (Java-like) or a virtual function cannot be rewritten (similar to sealed in C #). If the modifier function, final can only modify the virtual function, and will be placed behind the class or function.
struct a{ virtual void foo () final;//Foo declared as final virtual function, cannot be overridden by Void Test () Final;//error, Final can only modify virtual function};struct B Fina l{//b Declaration is final, indicating that it cannot be inherited};struct c:b{//error, B cannot be inherited};
The override keyword is also added in c++11 to ensure that the overriding function declared in the derived class has the same signature as the virtual function of the base class, as well as a clear indication that the virtual function of the base class will be overridden, as well as to prevent inadvertent declaration of the virtual function that originally intended to override the base class as overloaded. The override keyword should be placed after the method
struct a{ virtual void func ();}; struct d:a{ void func () override{ };};
5. Memory Alignment
When the CPU accesses the memory, the starting address is not arbitrary, for example, some CPU accesses the memory starting address in multiples of 4, because the memory bus width is 32 bits, each read and write operation is 4 bytes 4 bytes. If a data is not byte-aligned in memory, it can be cumbersome to access, such as a 4-byte int32 type with no 4-byte alignment, and two memory accesses to read the full data. Therefore, memory alignment can improve the efficiency of the program.
C + + data memory alignment means that the starting address of the data in memory is a multiple of the size of the data. The principle of the internal alignment of C + + structures is that each variable in the structure is aligned itself, such as Int32 4-byte alignment, char 1-byte alignment, and the entire structure is aligned according to the maximum size variable in the structure, such as
struct{ int A; char c; Double D;}; The struct is aligned according to the variable of the maximum size, which is 8 bytes of the double.
For structs, the default alignment is equal to the alignment value of the largest member. Also, when the memory alignment of a struct is limited, the memory alignment of all members of the struct must not exceed the memory alignment of the struct itself.
Use Alignas to specify memory alignment size
Alignas (+) long long a = 0; Specifies that a is 32-byte aligned. Alignas can change the memory alignment to large, //And not small, so there can be Alignas (a) long long A; and cannot have Alignas (1) long long A; #define XX 1 struct Alignas (XX) mystruct{//is specified as 1-byte alignment because there is no data inside the mystruct, naturally 1-byte alignment. //If the interior contains int type data, then the Alignas can only be modified by the alignment method can not be changed to small, it cannot be 1-byte alignment };
Alignas only the memory alignment can not be changed to small, if you want to small, set the memory alignment to 1-byte alignment, still need to use the #pragma pack (1) .... #pragma pack ()
use alignof and std::alignment_of to get memory alignment size
Alignof can only return size_t, which is the size of memory alignment, and Alignment_of inherits from Std::integral_constant, with members such as Value_type, type, and value.
MyStruct xx; cout << alignof (xx) << Endl; cout << alignof (mystruct) << Endl; cout << std::alignment_of<mystruct<::value << Std::endl;
Memory-aligned type Std::aligned_storage
The aligned_storage can be viewed as a memory-aligned buffer with the following prototype:
template<std::size_t Len, std::size_t Align =/*default-alignment*/>struct aligned_storage; Len represents the size,align of the stored type representing the alignment size of the stored type struct a{ int A; Double C; A (int AA, double cc): A (AA), C (cc) {};}; typedef std::aligned_storage<sizeof<a> alignof (A) >::type Aligned_a;int Main () { aligned_a A, B;// Declares a piece of memory-aligned memory new (&a) A (10, 20.0);//In-situ constructor return 0;}
C++11 Other features (i)