Default Methods in C++ with Examples
If we write a class that has no methods in it, and the class does not inherit from another class, the compiler will add six methods to it automatically. The methods which can be automatically generated by the compiler are:
- Default Constructor: It is equivalent to an empty default constructor. The default constructor is a constructor which can be called with no arguments. It is called when an instance is created without initialization.
class_name object_name;
- Consider a class derived from another class with the default constructor, or a class containing another class object with default constructor. The compiler needs to insert code to call the default constructors of base class/embedded object.
CPP
#include <iostream>
using namespace std;
class Base {
public :
};
class A {
public :
A()
{
cout << "A Constructor" << endl;
}
int size;
};
class B : public A {
};
class C : public A {
public :
C()
{
cout << "C Constructor" << endl;
}
};
class D {
public :
D()
{
cout << "D Constructor" << endl;
}
private :
A a;
};
int main()
{
Base base;
B b;
C c;
D d;
return 0;
}
|
Output:
A Constructor
A Constructor
C Constructor
A Constructor
D Constructor
-
- Destructor: It is equivalent to an empty destructor. It calls the superclass destructor and the destructors for member fields that are not of primitive type. The general form of declaring a destructor is follows:
class_name::~class_name;
- Example for Destructor:
CPP
#include <iostream>
using namespace std;
class Example {
private :
int a, b;
public :
Example()
{
cout << "Constructor is called"
<< endl;
a = 10;
b = 20;
}
~Example()
{
cout << "Destructor is called"
<< endl;
}
void print()
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
};
int main()
{
Example obj;
obj.print();
return 0;
}
|
-
Output:
Constructor is called
a = 10
b = 20
Destructor is called
-
- Copy Constructor: Copy constructor is a constructor which can be called with a reference to a class instance as an argument. It is called when a new copy of an instance needs to be initialized either explicitly or implicitly by the compiler, e.g., when an instance is passed by value to a function or is returned by value. It initializes every instance member with a corresponding member of the constructor’s argument.
Below program demonstrates the use of Copy Constructor for better understanding.
- Copy assignment operator: It is equivalent to an assignment operator that assigns every member of its argument to a corresponding member of this instance. Note that this may lead to calls to the member’s fields own copy assignment operators.
MyClass t1, t2;
// copy constructor is called
MyClass t3 = t1;
// copy assignment operator is called
t2 = t1;
- Example for Copy Constructor and Copy Assignment Operator:
CPP
#include <iostream>
using namespace std;
class Line {
public :
Line( int len);
Line( const Line& obj);
void display( void );
private :
int * ptr;
};
Line::Line( int len)
{
ptr = new int ;
*ptr = len;
}
Line::Line( const Line& obj)
{
cout << "Copy constructor allocating ptr."
<< endl;
ptr = new int ;
*ptr = *obj.ptr;
}
void Line::display()
{
cout << "Length of line: "
<< *ptr << endl;
}
int main()
{
Line l1(10), l2(0);
Line l3 = l1;
l2 = l1;
l1.display();
l2.display();
l3.display();
return 0;
}
|
-
- Move Constructor: The move constructor is a constructor which can be called with an rvalue reference to a class instance as an argument, typically ClassName(const ClassName&&). It is called when a new instance is initialized from a temporary object that typically is destroyed after initialization, e.g., when returning by value from a function or an explicit call as in ClassName new_instance(std::move(existing_instance)).
- Move Assignment Operator: C++11 defines two new functions related to move semantics: a move constructor, and a move assignment operator. Whereas the goal of the copy constructor and copy assignment is copied one object into another, the goal of the move constructor and move assignment is to move ownership of the resources from one object to another (which is much less expensive than making a copy).
Example for Move Constructor and Move Assignment Operator:
CPP
#include <iostream>
using namespace std;
struct S {
int * p;
int n;
S(S&& other)
: p{ exchange(other.p, nullptr) }, n{ exchange(other.n, 0) }
{
}
S& operator=(S&& other)
{
p = exchange(other.p, nullptr);
n = exchange(other.n, 0);
return * this ;
}
};
|
- Defining a move constructor and move assignment work equivalently to their copy counterparts. However, whereas the copy flavours of these functions take a const lvalue reference parameter, the move flavours of these functions use non-const r-value reference parameters.
Note: It is important to be aware of these functions. The problem is not in their existence but that we are not forced to write our own and may forget to so in cases where trivial copy/initialization will not work.
For example the following program prints 1 then -2. This is because the default copy assignment operator copies the raw pointer to b2.
CPP
#include <bits/stdc++.h>
using namespace std;
class Buffer {
public :
Buffer( int size, int * buffer)
: size(size), buffer(buffer)
{
}
int size;
int * buffer;
};
int main()
{
const int kBufSize = 2;
int * buffer = new int [kBufSize]{ 1, 2 };
Buffer b1 = Buffer(kBufSize, buffer);
cout << b1.buffer[0] << endl;
Buffer b2 = b1;
b2.buffer[0] = -2;
cout << b2.buffer[0] << endl;
return 0;
}
|
Similar problems abound when using the default constructor and destructor—fields are not initialized, memory is not reclaimed, etc. In short, we should be aware that copying and initialization objects are our responsibility.
Last Updated :
29 Jul, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...