Before, we check how to stop copy of object, lets see that a class objects can be copied in 2 cases,
- During creation of object by copying another object (using a copy constructor)
- Simply using assignment operator to copy all the contents of another objects.
Stop Copy: The class need to hide both copy constructor and the assignment operator to make it uncopiable. Even if the class do not define these, the compiler will automatically generate both functions.
Private scope: Therefore, class should provide both the declarations under private scope. There is no need to provide the definition because the definition is not supposed to be called anytime.
#include <iostream> //main header
using namespace std; //namespace
class myuncopyable
{
private:
myuncopyable(const myuncopyable& rhs);
myuncopyable& operator= (const myuncopyable& rhs);
public:
myuncopyable(){}
};
int main()
{
myuncopyable u1;
myuncopyable u2 = u1; //This should fail
myuncopiable u3;
u3 = u1; //This should also fail
return 0;
}
The compiler returns the error:
Uncopyable Base class
If any class derives from the uncopiable class then also the derived class will automatically become uncopiable because now the base class part cannot be copied. Therefore, the compiler cannot generate or call copy constructor of Base class
#include <iostream> //main header
using namespace std; //namespace
class myuncopyable
{
private:
myuncopyable(const myuncopyable& rhs);
myuncopyable& operator= (const myuncopyable& rhs);
public:
myuncopyable(){}
};
class Derived : public myuncopyable
{
};
int main()
{
Derived d1;
Derived d2 = d1;
return 0;
}
The output will be:
Loophole:
There is a loophole in this method that if the copy or assignment is done from friend function or from existing member function, then compilation will become successful. However, there is no definition provided so the linker will fail.
#include <iostream> //main header
using namespace std; //namespace
class myuncopyable
{
private:
myuncopyable(const myuncopyable& rhs);
myuncopyable& operator= (const myuncopyable& rhs);
public:
myuncopyable(){}
void makeAnotherCopy()
{
myuncopyable u = *this;
//copy constructor from member
}
};
int main()
{
myuncopyable u1;
u1.makeAnotherCopy();
return 0;
}
The linker may be as follows:
The method explained is used in standard C++ but this is more like a workaround and not a standard method.
In C++11, there is a proper method to make class object unable to copied.