Defaulted and Deleted Methods

C++11 provides more control over which methods are used. Suppose that you wish to use a defaulted function that, due to circumstances, isn’t created automatically. For example, if you provide a move constructor, then the default constructor, the copy constructor, and the copy assignment operator are not provided. In that case, you can use the keyword default to explicitly declare the defaulted versions of these methods:

class Someclass
{
public:
   Someclass(Someclass &&);
   Someclass() = default;      // use compiler-generated default constructor
   Someclass(const Someclass &) = default;
   Someclass & operator=(const Someclass &) = default;
...
};

The compiler provides the same constructor that it would have provided automatically had you not provided the move constructor.

The delete keyword, on the other hand, can be used to prevent the compiler from using a particular method. For example, to prevent an object from being copied, you can disable the copy constructor and copy assignment operator:

class Someclass
{
public:
   Someclass() = default;      // use compiler-generated default constructor
// disable copy constructor and copy assignment operator:
   Someclass(const Someclass &) = delete;
   Someclass & operator=(const Someclass &) = delete;
// use compiler-generated move constructor and move assignment operator:
   Someclass(Someclass &&) = default;
   Someclass & operator=(Someclass &&) = default;
   Someclass & operator+(const Someclass &) const;
...
};

You may recall (from Chapter 12) that you can disable copying by placing the copy constructor and assignment operator in the private section of a class. But using delete is a less devious and more easily understood way to accomplish that end.

What is the effect of disabling copy methods while enabling move methods? Recall that an rvalue reference, such as used by move operations, binds only to rvalue expressions. This implies the following:

Someclass one;
Someclass two;
Someclass three(one);       // not allowed, one an lvalue
Someclass four(one + two);  // allowed, expression is an rvalue

Only the six special member functions can be defaulted, but you can use delete with any member function. One possible use is to disable certain conversions. Suppose, for example, that the Someclass class has a method with a type double parameter:

class Someclass
{
public:
...
    void redo(double);
...
};

Then suppose we have the following code:

Someclass sc;
sc.redo(5);

The int value 5 will be promoted to 5.0, and the redo() method will execute.

Now suppose the Someclass definition is modified thusly:

class Someclass
{
public:
...
    void redo(double);
    void redo(int) = delete;
...
};

In this case, the method call sc.redo(5) matches the redo(int) prototype. The compiler will detect that fact and also detect that redo(int) is deleted, and it will then flag the call as a compile-time error. This illustrates an important fact about deleted functions. They do exist as far as function look-up is concerned, but to use them is an error.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.47.169