The C++ compiler generates following member functions the user do not declare them in class.
- Default constructor
- Copy constructor
- Assignment operator
- Destructor
Compiler will generate only if needed:
The compiler will generate these functions only when it needs them. Example, i.e., if a copy operation is happening only then compiler generates a copy constructor. Secondly, if an object to created & destroyed, then a default constructor & destructor will be created.
class MainFunda
{
};
MainFunda aobj1; //Needs constructor & destructor
MainFunda aobj2 = obj1; //Needs copy constructor & destructor
aobj2 = aobj1; //needs assignment operator
Compiler will generate only if it is possible:
Secondly, the compiler generates special functions only if it is technically possible in context of class. For example, if the compiler cannot copy an object, then it will not generate a copy constructor.
#include <iostream> //main header
using namespace std; //namespace
class MainFunda
{
int& ix;
public:
MainFunda(int param): ix(param) {}
};
int main()
{
int im = 9;
MainFunda a1(im);
MainFunda a2(im);
a1 = a2; //This line is problematic
return 0;
}
The compiler will generate following error:
Here the member ix is a reference and reference cannot be modified therefore compiler is not able to generate code for assignment operator.
Another Example where compiler cannot generate functions:
Similarly, if the member variable is a constant then also compiler cannot modify a constant. Hence, the compiler will not generate an assignment operator.
#include <iostream> //main header
using namespace std; //namespace
class MainFunda
{
const int ix = 1;
};
int main()
{
MainFunda a1;
MainFunda a2;
a1 = a2;
return 0;
}
Compiler generates the following error in this case:
With Inheritance: If class MainFunda would have been a Base class, then same problem will happen with all the derived classes, even if they had valid assignment operator.
#include <iostream> //main header
using namespace std; //namespace
class MainFunda
{
const int ix = 1;
};
class MFDerived : public MainFunda
{
};
int main()
{
MFDerived b1;
MFDerived b2;
b1 = b2; //This is problematic
return 0;
}
The output is:
Properties of generated copy constructor & assignment operator
For both the copy constructor and the copy assignment operator, the compiler-generated versions simply copy each non-static data member of the source object over to the target object.
By default, the compiler will copy all the data members (object or built-in type) as bitwise copy of the original object. However, if the user has provided a copy constructor then corresponding copy constructor will be called.
#include <iostream> //main header
using namespace std; //namespace
class withCopyConst
{
int ix;
public:
withCopyConst() : ix(0) {}
withCopyConst(const withCopyConst& rhs)
{
ix = rhs.ix;
cout << "Copy Constructor Called";
}
};
class withoutCopyConst
{
int iy;
};
class MainFunda
{
withCopyConst c1;
withoutCopyConst c2;
};
int main()
{
MainFunda a1;
MainFunda a2 = a1;
return 0;
}
The output will be:
Copy Constructor Called
Firstly, for the class withCopyConst, the compiler will call a user-defined copy constructor.
Secondly, for the class withoutCopyConst, the compiler will call generated copy constructor .
Similarly, if there is a base class, then C++ compiler will construct the base class part by calling corresponding copy constructor (in base class).
Same is true for assignment operator.
If copy constructor exists then also default constructor not generated:
If class defines at least one constructor then compiler will not generate other constructors. Like, if a class defines copy constructor then compiler will think that there is something special about the creation. Therefore, the compiler will not generate a regular constructor.
#include <iostream> //main header
using namespace std; //namespace
class MainFunda
{
public:
MainFunda(const MainFunda& rhs)
{
cout << "Copy Constructor Called";
}
};
int main()
{
MainFunda a1;
return 0;
}
The compiler will throw error: