What should I do if I want to block the copy or assignment operation of an object?
Class HomeForSale {};
HomeForSale h1;
HomeForSale h2;
HomeForSale h3 (h1); // an attempt is made to call the copy constructor of h3 to clone an h1
H1 = h2; // an attempt to call the copy assignment operation to assign the intact h2 object to h1
The above two examples both copy or assign values to an object. The two statements are different, the syntax is different, and the call time is different, but the internal implementation is similar. For example, we should avoid the emergence of the above two examples.
It is not intuitive to block compilation of this type of code. Generally, we don't want to declare and implement the corresponding functions if we don't want an object to have an operation, this is true for general functions, but the two functions we want to block have some special features. Even if we do not display the declaration and implementation of these two functions, the compiler will implement a compiler version for us as long as our code has one of the two requirements during execution. How is it good?
The answer is: The functions automatically generated by the compiler for users are all public functions. We can declare these two functions as private because we will not call them, therefore, we only want to keep them private instead of implementing them. This achieves two goals: 1. The declaration shown in 1 is private. The compiler will no longer create a compiler version for us if it knows the manually declared function, there will be no public functions. 2. Don't implement it, because we won't call them, so it's just a superfluous addition.
The member functions of the class or the friend functions of the class have the right to go to the private domain of the member class. However, if you call them at this time, you will receive a link error because these two functions are not implemented. What we can do is to avoid calling them as much as possible.
In this way, the previous Code is as follows:
HomeForSale h1; // No constructors are available
HomeForSale h2; // same as above
HomeForSale h3 (h1); // an attempt is made to call the copy constructor of h3 to clone an h1, and private functions cannot be called.
H1 = h2; // an attempt is made to call the copy assignment operation to assign the h2 object intact to h1, and private functions cannot be called.
It is feasible to transfer a link-time error to the compiler, that is, to design the base class.
Class Uncopyable
{
Protected:
Uncopyable (){}
~ Uncopyable () {}// The Destructor is not designed as virtual even for the base class, so there is no need to release objects dynamically here.
Private:
Uncopyable (const Uncopyable & c );
Uncopyable & operator = (const Uncopyable & c );
};
Class HomeForSale: public Uncopyable
{
// At this time, the class does not need to declare the copy constructor and the copy assignment operator.
};
Anyone here, even if a member function or a friend function tries to copy HomeForSale, the compiler will try to generate a copy constructor or copy assignment operator and will call the corresponding functions of its base class, the compiler fails to generate because the base class is private. Throws a compiler error and early detection of the problem.