1 default function
Design a class with no member functions (member function), only member data (member)
class dataonly {private: std::string strName; // member data int IData;};
1.1 Special member functions
The c++98 compiler implicitly produces four functions: default constructor , destructor , copy constructor , copy assignment operator
The c++11 compiler, in addition to generating these four functions, will produce two more functions: Moving Constructors , moving assignment operators
classdataonly { Public: DataOnly ()//default constructor~dataonly ()//destructor
DataOnly (ConstDataOnly & RHS)//copy ConstructorDataOnly &operator=(ConstDataOnly & RHS)//Copy assignment operator
DataOnly (ConstDataOnly && RHS)//c++11, move constructorDataOnly &operator= (dataonly && RHS)//c++11, move assignment operator};
1.2 Two implementation forms
The default constructor is to initialize the class's member data, which is equivalent to the following form:
DataOnly::D ataonly (const dataonly &orig): StrName (Orig.strname), IData (Orig.idata) {}
The implementation of the copy assignment operator is equivalent to the following form:
dataonly& dataonly::operator= (const dataonly &rhs) { = rhs.strname; // calls the string::operator= IData = Rhs.idata; // uses the built-in int assignment return *this; // return a referenceto this object}
Why the end returns *this, see the "1.1-chained assignment" in the overloaded assignment operator for C + + in another blog post
2 Disable default functions
As a developer, this function is not declared if you do not want the user to use a class member function, but it is another case for special member functions (special member Fucntions) that are generated automatically by the compiler.
For example, design a leaf class as follows:
class Leaffromtree{...};
Leibniz said, " there are no two identical leaves in the World " (Es gibt keine zwei Blätter, die Gleich bleiben), therefore, for a unique leaf, the following operation is wrong.
Leaffromtree LEAF1; Leaffromtree leaf2; Leaffromtree Leaf3 (LEAF1); // attempt to copy leaf1-should not compile! LEAF1 = Leaf2; // attempt to copy leaf2-should not compile!
As the above code shows, you need to avoid using copy constructor and copy assignment operator.
2.1 Private + Not implemented
C++98, these special member functions can be declared private, and the function is not implemented, as follows:
class leaffromtree{private: const leaffromtree&); // Not defined operator Const leaffromtree&); // Not defined};
If the copy constructor (or copy assignment operator) of the Leaffromtree class is called in the program, a link error (link-time error) will occur at compile time
In order to advance the error to compile time (compile), a base class uncopyableis added, and the copy constructor and copy assignment operator are declared as private
class uncopyable {protected: uncopyable () {} //Allow construction and destruction of derived objects ... ~private: uncopyable (const uncopyable&); // ... but prevent copying operator= (const uncopyable&);};
And Leaffromtree is privately inherited from the Uncopyable base class.
// class no longer declares copy ctor or copy assign operator class Private uncopyable {};
2.2 Delete keyword
C++11 is simpler, simply add "= delete" After a function declaration that you want to "disable", add "= Default" or do not take action
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 Extension of Delete
in c++11, the DELETE keyword can be used for any function, not just class member functions
3.1 Function overloading
In the function overload, delete is used to filter out the formal parameter types of some functions, as follows:
bool islucky (int number); // bool islucky (char ) = delete ; // Reject chars bool islucky (bool ) = delete ; // Reject Bools bool islucky (double ) = delete ; // Reject doubles and floats
This causes an error message if the parameter type is incorrect when calling the Islucky function.
if (Islucky ('a')) ... // Error! Call to deleted functionif (Islucky (true)) ... // Error! if (Islucky (3.5)) ... // Error!
3.2 Template specificity
In template specialization, you can also use Delete to filter some specific parameter types.
For example, a template function is declared in theWidget class, and a function call that has a void* parameter is required when template specificity is made.
If you follow c++98 's "Private non-implementation" approach, you should declare an exceptional function as private, as follows:
class Widget {public: template<typename t> void processpointer (t* PTR) {...} Private : template<> void processpointer<void> (void*); // error!};
The problem is that template specificity should be written in the namespace domain (namespace scope), not the class scope, so the method will error.
In C++11, because of the DELETE keyword, you can declare a special template function as delete directly outside of the class, as follows:
class Widget {public: template<typename t> void processpointer (t* PTR) {...}}; Templatevoid Widget::p rocesspointer<void> (voidDelete// still public, but deleted
Thus, when the program code, there is called void* as formal parameters of the Processpointer function, the compile will be error.
Summary:
1) Prefer deleted functions to private undefined ones
2) Any function could be deleted, including Non-member functions and template instantiations
Resources:
<c++ primer_5th> Chapter Copy Control
<effective c++_3rd> Item 5, item 6
<effective modern c++> Item one, item 17
c++11 "= delete"