Traditional Approach – make them private
To avoid compiler generated constructor and other special functions, a class may declare such functions as private. Basically, the four special member functions are –
- constructor
- copy constructor,
- assignment operator
- Destructor
When a class just provides declaration in such functions, then compiler shall not auto-generate them. Additionally, the class must declare them under private scope. In this way, a client code can not access them.
In the following example, a class MainFunda do not want a Copy Constructor and Assignment operator. Therefore, both the declarations are under private and without a definition body.
However, the compiler shall still create members which do not have any mention (example, destructor in this case)
#include <iostream> //main header
using namespace std; //for namespace
class MainFunda
{
private:
MainFunda(const MainFunda& rhs);//copy constructor
MainFunda& operator=(const MainFunda& rhs); //assignment
public:
MainFunda() {}
};
int main()
{
MainFunda a1;
MainFunda a2(a1); //Invokes copy constructor
MainFunda a3;
a3 = a1; // Invokes assignment operator
return 0;
}
The output is:
Problems with Traditional private approach
Consequently, such traditional approach is more a work-around and is not a standard solution. Therefore, it has problems.
- The error which comes during compilation is weird. The compiler always says that given function is private and therefore cannot access it. Ultimately, the message is not pointing to the real issue. That this class do not wants an auto-generation of these special functions.
- Secondly, the method is not fool-proof. The private member functions are still accessible in some scenarios. Example, any class member or, a friend classes or functions can still call. Therefore, such calls can lead to Linker-Error. This is even more weird. Because, it means that syntactically the operations were correct, only the class is missing some implementation.
Modern C++11 Approach
For how to avoid compiler generated constructor problem, C++11 has come-up with a very good solution. Now, firstly, the class shall use the keyword “delete” to hide any function. And secondly, the compiler shall understand the background and shall generate a valid error. Although, the delete keyword was already there, but now C++11 provides a new role.
In the same example, now the class MainFunda hides the copy constructor and assignment using “delete”.
#include <iostream> //main header
using namespace std; //for namespace
class MainFunda
{
public:
MainFunda(const MainFunda& rhs) = delete;
//copy constructor
MainFunda& operator=(const MainFunda& rhs) = delete;
//assignment operator
MainFunda() {}
};
int main()
{
MainFunda a1;
MainFunda a2(a1); //Invokes copy constructor
MainFunda a3;
a3 = a1; //Invokes assignment operator
return 0;
}
The output shall be: