Two new features of the C ++ 11 standard

Source: Internet
Author: User
Tags ibm developerworks

Introduction:

This article introduces two new features of the C ++ 11 standard: defaulted and deleted functions. For the defaulted function, the compiler automatically generates the default Function Definition body for it to achieve higher code execution efficiency. It can also help programmers manually define the function. For the deleted function, the compiler will disable it to avoid some illegal function calls or type conversion, thus improving the code security. This article describes in detail the usage and benefits of defaulted and deleted functions through code examples.

Defaulted Function

Background

C ++ has four types of special member functions: default constructor, destructor, copy constructor, and copy value assignment operator. Special member functions of these classes are responsible for creating, initializing, and destroying, or copying class objects. If the programmer does not explicitly define a special member function for a class and needs to use this special member function, the compiler will implicitly generate a default special member function for this class. For example:

Listing 1

class X{  private:   int a;  };  X x;

In list 1, the programmer does not define the default constructor of class X. However, when creating the object X of Class x, the default constructor of Class X needs to be used, the compiler implicitly generates a default constructor for class X. The automatically generated default constructor has no parameters and contains an empty function body, that is, X: X (){}. Although the automatically generated default constructor has only one empty function body, it can still be used to successfully create the object X of class x. Listing 1 can also be compiled.

However, if the programmer explicitly creates a non-default constructor for Class X but does not define the default constructor, the compilation error in Listing 2 will occur:

Listing 2

Class X {public: X (int I) {a = I;} private: int a ;}; X x X; // error. The default constructor X: X () does not exist.

In Listing 2, the cause of compilation error is that Class X already has a user-defined constructor, so the compiler will no longer generate default constructor for it implicitly. If you need to use the default constructor to create class objects, the programmer must explicitly define the default constructor. For example:

Listing 3

Class X {public: X () {}; // manually define the default constructor X (int I) {a = I;} private: int a ;}; X x X; // correct. The default constructor X: X () exists.

From list 3, we can see that the default constructor originally expected to be automatically generated by the compiler needs to be manually written by the programmer, that is, the workload of the programmer increases. In addition, the code execution efficiency of the default constructor manually compiled is lower than that of the default constructor automatically generated by the compiler. The other types of special member functions of the class are the same as those of the default constructor. When a user-defined special member function exists, the compiler does not automatically generate the default special member function, but it requires programmers to write it manually, which increases the workload of programmers. Similarly, code execution efficiency of special member functions manually written is lower than that of special member functions automatically generated by the compiler.

Proposal of the Defaulted Function

To solve the two problems shown in listing 3: 1. reduce programmer programming workload; 2. to achieve high code execution efficiency of the default special member functions automatically generated by the compiler, the C ++ 11 standard introduces a new feature: the defaulted function. The programmer only needs to add "= default;" after the function declaration to declare the function as the defaulted function. The compiler will automatically generate the function body for the explicitly declared defaulted function. For example:

Listing 4

class X{  public:   X()= default;   X(int i){     a = i;   }      private:   int a;  };  X x;

In Listing 4, the compiler automatically generates the default constructor X: X () {}, which is more efficient than the User-Defined default constructor.

Defaulted Function Definition syntax

The Defaulted function is a new syntax for Function Definition introduced in the C ++ 11 standard. The Syntax 1 defined by the defaulted function is as follows:

Figure 1. ulted Function Definition syntax

Usage and example of the Defaulted Function

The Defaulted function is only applicable to special member functions of the class, and this special member function has no default parameters. For example:

Listing 5

Class X {public: int f () = default; // error, function f () is not a special member function of class X (int) = default; // error, the special member function X (int = 1) of the constructor X (int, int) not X = default; // error, default constructor X (int = 1) contains default parameters };

The Defaulted function can be defined either in the inline or in the out-of-line class. For example:

Listing 6

Class X {public: X () = default; // Inline defaulted default constructor X (const X &); X & operator = (const X &);~ X () = default; // Inline defaulted destructor}; X: X (const X &) = default; // Out-of-line defaulted copy constructor X & X: operator = (const X &) = default; // Out-of-line defaulted // copy value assignment operator

During C ++ code compilation, if the programmer does not define the Destructor for Class X, but needs to call the Destructor for Class X when destroying Class X objects, the compiler automatically and implicitly generates a destructor for the class. The automatically generated destructor has no parameters and contains an empty function body, that is, X ::~ X (){}. For example:

Listing 7

class X {  private:   int x;  };  class Y: public X {  private:   int y;  };  int main(){   X* x = new Y;   delete x;  }

In listing 7, the programmer does not define the Destructor for the base class X and the derived class Y. When deleting the base class pointer x in the main function, the programmer needs to call the base class destructor. Therefore, the compiler automatically and implicitly generates an destructor for Class X to successfully destroy the base class sub-objects (that is, the int type member variable x) in the derived class object to which x points ).

However, this Code may cause memory leakage. When the delete statement is used to delete the pointer x pointing to the object of the derived class, the system calls the basic class destructor, instead of the destructor of the derived class Y, the compiler cannot parse the int-type member variable y of the derived class.

Therefore, we usually need to define the destructor of the base class as a virtual function. When the delete statement is used to delete the base class pointer pointing to the object of the derived class, the system calls the destructor of the corresponding derived class (implementing polymorphism) to avoid Memory leakage. However, all automatically generated destructor by the compiler are non-virtual functions. This requires programmers to manually define virtual destructor for Class X, for example:

Listing 8

Class X {public: virtual ~ X () {}; // manually define the virtual destructor private: int x ;}; class Y: public X {private: int y ;}; int main () {X * x = new Y; delete x ;}

In listing 8, since the programmer manually defines a virtual destructor for Class X, when the delete statement is used to delete the base class pointer x pointing to the object of the derived class, the system calls the corresponding destructor of the derived class Y (automatically generated by the compiler) and the destructor of the base class X to completely destroy the derived class object and avoid Memory leakage.

However, in listing 8, the programmer needs to manually write the definition of the fictitious function of the base class (even if the function body is empty), increasing the programmer's programming workload. It is worth mentioning that the code execution efficiency of manually defined destructor is lower than that automatically generated by the compiler.

To solve the above problem, we can declare the virtual destructor of the base class as the defaulted function, so that we can explicitly specify the compiler to automatically generate the function body for the function. For example:

Listing 9

Class X {public: virtual ~ X () = defaulted; // The Compiler automatically generates the ulted Function Definition body private: int x ;}; class Y: public X {private: int y ;}; int main () {X * x = new Y; delete x;

}

In listing 9, the compiler automatically generates the virtual destructor virtual X: X (){}, this function is more efficient in code execution than a self-defined virtual destructor.

Deleted Function

Background

For C ++ classes, if the programmer does not define special member functions for them, when a special member function is required, the compiler automatically generates a default special member function, such as a copy constructor or a copy value assignment operator. For example:

Listing 10

Class X {public: X () ;}; int main () {X x1; X x2 = x1; // correct. Call the default copy constructor X x3 generated by the compiler implicitly; x3 = x1; // correct. Call the default copy assignment operator implicitly generated by the compiler}

In listing 10, programmers do not need to manually write the copy constructor and copy the value assignment operator, the default copy constructor automatically generated by the compiler and the copy assignment operator can be used to copy and assign values to class objects. This is convenient and convenient in some cases, but in some cases, suppose we do not allow copying and assigning values between class objects, however, the compiler cannot automatically generate default copy constructor and copy the value assignment operator by implicit means, which becomes a problem.

Proposal of the deleted Function

To enable the programmer to explicitly disable a function, the C ++ 11 standard introduces a new feature: the deleted function. The programmer can disable the function by adding "= Delete;" after the function declaration. For example, we can declare the copy constructor of Class X and the copy assignment operator as the deleted function to prohibit copying and assigning values between Class X objects.

Listing 11

Class X {public: X (); X (const X &) = delete; // declare the copy constructor as the deleted Function X & operator = (const X &) = delete; // declare the copy assignment operator as the deleted function}; int main () {X x1; X x2 = x1; // The copy constructor is disabled X x3; x3 = x1; // error. The copy assignment operator is disabled}

In listing 11, although only one copy constructor and one copy assignment operator are explicitly disabled, however, since the compiler detects that Class X has a user-defined copy constructor and copy value assignment operator declaration, it will no longer generate a copy constructor of other parameter types or copy value assignment operators implicitly, it is equivalent to Class X without any copy constructor or copy assignment operator, So copying and assignment between objects is totally forbidden.

Deleted Function Definition syntax

The deleted function is a new syntax for Function Definition introduced in the C ++ 11 standard. Syntax 2 of the deleted function definition is shown below:

Figure 2. ED function definition syntax

Deleted function usage and example

The deleted function feature can also be used to disable some conversion constructors of classes to avoid unexpected type conversion. In listing 12, assume that Class X only supports the conversion constructor of the double-precision floating point number type, but does not support the conversion constructor of the integer int type, you can declare the int type conversion constructor as the deleted function.

List 12

Class X {public: X (double); X (int) = delete ;}; int main () {X x1 (1.2); X x2 (2); // error, converted constructors whose parameters are integer int type are disabled}

The Deleted function feature can also be used to disable the new operators of some user-defined classes to avoid creating class objects in the free storage area. For example:

Listing 13

# Include <cstddef> using namespace std; class X {public: void * operator new (size_t) = delete; void * operator new [] (size_t) = delete ;}; int main () {X * pa = new X; // error. The new operator is disabled. X * pb = new X [10]; // error, new [] OPERATOR disabled}

The function must be declared as the deleted function when it is declared for the first time. Otherwise, the compiler reports an error. That is, for a class member function, the deleted function must be defined in the class body (inline) and cannot be defined in the out-of-line class. For example:

Listing 14

Class X {public: X (const X &) ;}; X: X (const X &) = delete; // error. The deleted function must be declared at the first declaration of the function.

Although the defaulted function feature specifies that only special member functions of the class can be declared as the defaulted function, the deleted function feature does not have this restriction. Non-class member functions, that is, normal functions can also be declared as deleted functions. For example:

Listing 15

Int add (int, int) = delete; int main () {int a, B; add (a, B); // error, function add (int, int) disabled}

It is worth mentioning that in listing 15, although the add (int, int) function is disabled, only the function definition is disabled, that is, the function cannot be called. However, the Function Identifier add is still valid. The function identifier is still found during name search and function reload parsing. If the compiler parses the reload function and returns the deleted function, a compilation error occurs. For example:

Listing 16

# Include <iostream> using namespace std; int add (int, int) = delete; double add (double a, double B) {return a + B;} int main () {cout <add (1.2) <endl; // error. The add ed function add (int, int) cout <add (1.3,) <endl; return 0 ;}

Conclusion

This topic describes the new features of C ++ 11: defaulted and deleted functions. This feature cleverly expands the syntax of the existing C ++ keywords default and delete, and introduces two new function definition methods: Add = default and = delete after the function declaration. By declaring a special member function of a class as a defaulted function, you can explicitly specify that the compiler automatically generates the default function body for this function. By declaring a function as a deleted function, you can disable some undesirable conversions or operators. The Defaulted and deleted functions have simple syntax and functions.
A very valuable extension of the standard.

Source: IBM developerWorks

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.