Rule of Zero/Three/Five
Constructor
Same named function of class. Ctr is cal led when object of class is
created. Used to provide values to data members.
Return type=None, Cannot access to address of ctr, Inheriting
ctr=Cannot
PRIVATE SCOPED CTR*: Can ctr be inside private section(Yes. Single DP)
Ctr calling Hierarchy (Base Class > Derv Class Ctr) |
Base class constructor should be defined |
Ctr Initializer list |
|---|---|---|
|
Derived class object also have inherited properties of Base class,
and only base class constructor can properly initialize base class members
|
C++ will always call Base ctr 1st Either user has provide definition (A(){}) Or user can remove his contructor. Compiler will add its default ctr
|
In the initializer list, the order of execution takes place
according to the order of declaration of member variables.
|
Types of Constructors
1. Copy Constructor
-
Copy Ctr is
L Value Refererence. Creates copy of object
| Default Copy Constructor(Shallow Copy) | User-Defined Copy Constructor (Deep Copy) |
|---|---|
|
If you don't define a copy constructor, the
compiler provides a default one that performs a shallow,
member-wise copy. This works well for simple classes without dynamically allocated memory.
|
A user-defined copy constructor is necessary when a class has a
pointers to dynamically allocated memory. The default shallow copy would cause both objects to point to the same memory location, (e.g., a double-free error) when freed user-defined constructor below performs a deep copy by allocating new memory for the copied object.
|
2. Move Constructor(rvalue reference) (Introduced in c++11)
Move Semantics?
-
Helps transfer of ownership of resources from one object to another
without performing an deep copy.
Move constructor implements move semantics
Move Constructor
-
Moves the object.
Useful for temporary objects (rvalues) which are about to be destroyed anyway, instead of creating new deep copied object, Just transfer the ownership
using vi = vector <int>;
class A {
vi a;
void print() {
for (decltype(auto)i:a)
cout << i;
}
public:
//A(vi&& b):a(b) ///////// This will make copy. Not correct move ctr ///////////
A(vi&& b):a(move(b)) { // move ctr (using rvalue ref).
cout << "\nmove ctr\n";
print();
}
};
int main() {
vi a = {1,2,3};
A obj(a); // Copy ctr called. Local copy remains present
// move invokes a r value ref
A obj1(move(a)); // move(a) is equal to (int &&x = a)
cout << "\nAfter move ctr in main()\n";
for(decltype(auto)i:a)
cout << i;
}
/*
$ ./a.out
move ctr
1 2 3
After move ctr in main() //Value moved not availble in main
$
*/
delete the contructor
Introduced in C++11, = delete is an instruction telling the compiler to
explicitly disable a function. If any code tries to call that
function—or if the compiler will immediately throw a compile-time
error
Before C++11 Programmers used to hide functions by making them
private and leaving them unimplemented to prevent copying. However, that
old trick only caused linker errors later in the build process when
friend functions call it
class Database {
public:
Database() = delete; // Cannot do: Database db;
Database(string connectionString); // Must use this
};
Use Cases of =delete constructor
1. Classes that require parameters: Ensuring a class must be initialized
with specific data (e.g., A(int x) is provided, but A() = delete; forces
users to pass an integer).
2. Static-only utility classes: Classes that act merely as a namespace
for static helper functions and shouldn't ever be instantiated as
objects.
3. Singletons: Preventing multiple instances from being created
accidentally via default construction.