C ++ 11: "= delete", 11 delete
1 default Function
Design a class with no member function and only member data)
class DataOnly {private: std::string strName; // member data int iData;};
1.1 special member functions
The C ++ 98 compiler implicitly generates four functions:Default constructor,Destructor;Copy constructor,Copy assignment operator
In addition to the four functions, the C ++ 11 compiler generates two more functions:Mobile Constructor,Mobile assignment operator
class DataOnly {public: DataOnly () // default constructor ~DataOnly () // destructor
DataOnly (const DataOnly & rhs) // copy constructor DataOnly & operator=(const DataOnly & rhs) // copy assignment operator
DataOnly (const DataOnly && rhs) // C++11, move constructor DataOnly & operator=(DataOnly && rhs) // C++11, move assignment operator};
1.2 Two implementation forms
DefaultConstructorTo initialize the member data of the class, which is equivalent to the following form:
DataOnly::DataOnly(const DataOnly &orig): strName(orig.strName), iData(orig.iData) { }
WhileCopy assignment operatorIs equivalent to the following form:
DataOnly& DataOnly::operator=(const DataOnly &rhs){ strName = rhs.strName; // calls the string::operator= iData = rhs.iData; // uses the built-in int assignment return *this; // return a reference to this object}
Why is the end returned?* ThisFor more information, see"1.1 chain assignment"
2 disable default Functions
As a developer, if you do not want to use a class member function, do not declare this function. However, for special member functions (special member fucntions) automatically generated by the compiler ), this is another case.
For example, design a leaf class as follows:
class LeafFromTree{ ... };
Levenitz said, "There are no two identical leaves in the world "(Es Gibt Keine ZweiBlätter, dieGleich Bleiben). Therefore, the following operations are incorrect for a unique leaf.
LeafFromTree leaf1;LeafFromTree leaf2;LeafFromTree Leaf3(Leaf1); // attempt to copy Leaf1 — should not compile!Leaf1 = Leaf2; // attempt to copy Leaf2 — should not compile!
The code above shows thatAvoid using"Copy constructor" and "Copy assignment operator"
2.1 private + not implemented
In C ++ 98, you can declare these special member functions as private and do not implement them, as follows:
class LeafFromTree{private: LeafFromTree( const LeafFromTree& ); // not defined LeafFromTree & operator=( const LeafFromTree& ); // not defined};
If the LeafFromTree class copy constructor (or copy value assignment operator) is called in the program, a link-time error occurs during compilation)
To advance the error to compile time, you can add a base class Uncopyable, and declare the copy constructor and copy assignment operator as private.
class Uncopyable {protected: Uncopyable() {} // allow construction and destruction of derived objects... ~Uncopyable() {} private: Uncopyable(const Uncopyable&); // ...but prevent copying Uncopyable& operator=(const Uncopyable&);};
LeafFromTree is a private inheritance from the Uncopyable base class.
// class no longer declares copy ctor or copy assign operatorclass LeafFromTree: private Uncopyable { };
2.2 delete keywords
C ++ 11 is relatively simple. You only need to add"= Delete", Add"= Default"Or do not take the operation
class LeafFromTree{public: LeafFromTree() = default;
~LeafFromTree() = default;
LeafFromTree( const LeafFromTree& ) = delete; // mark copy ctor or copy assignment operator as deleted functions LeafFromTree & operator=( const LeafFromTree &) = delete;
};
3. delete Extension
In C ++ 11, the delete keyword can be used for any function, not limited to class member functions.
3.1 function Overloading
In function overloading, delete can be used to filter out the parameter types of some functions, as shown below:
bool isLucky(int number); // original functionbool isLucky(char) = delete; // reject charsbool isLucky(bool) = delete; // reject boolsbool isLucky(double) = delete; // reject doubles and floats
In this way, when the isLucky function is called, if the parameter type is incorrect, an error message is displayed.
if (isLucky('a')) … // error ! call to deleted functionif (isLucky(true)) … // error !if (isLucky(3.5)) … // error !
3.2 Special Template
In the template special case, you can also use delete to filter specific parameter types.
For example, a template function is declared in the Widget class. When the template is made special, it is required to disable function calls with the parameter void.
If C ++ 98's "Private not implemented" approach is followed, the special function should be declared as private, as shown below:
class Widget {public: template<typename T> void processPointer(T* ptr) { … }private: template<> void processPointer<void>(void*); // error!};
The problem is that the template specialization should be written in the namespace scope rather than the class scope. Therefore, this method will report an error.
In C ++ 11, the special template function can be declared as delete directly outside the class because of the delete keyword, as shown below:
class Widget {public: template<typename T> void processPointer(T* ptr) { … }};template<> void Widget::processPointer<void>(void*) = delete; // still public, but deleted
In this way, when the processPointer function of void * is called in the program code, an error is reported during compilation.
Summary:
1) PreferDeleted functionsTo private undefined ones
2) Any function may be deleted, includingNon-member functionsAndTemplate instantiations
References:
<C ++ Primer_5th> chapter 13 Copy Control
<Valid tive C ++ _ 3rd> item 5, item 6
<Valid tive Modern C ++> item 11, item 17