Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Copy Constructors | Constructors and Destructors
C++ OOP
course content

Contenido del Curso

C++ OOP

C++ OOP

1. Fundamentals of OOP
2. Constructors and Destructors
3. Encapsulation Overview
4. Inheritance Overview
5. Polymorphism Overview

bookCopy Constructors

There are two specialized constructors: the Copy Constructor and the Move Constructor. Understanding these constructors is crucial for effective resource management, memory allocation, and object manipulation

Copy Constructor

When copying two variables of a primitive type, the process is straightforward and doesn't usually require special consideration. However, copying objects in is a more complex and tricky task. The distinction between shallow copy and deep copy will become clear when you will examine the following code:

cpp

main

copy
1234567891011121314151617181920212223
#include <iostream> class Example { public: // Constructor that initializes p_data with a new integer value Example(int data) : p_data(new int(data)) { } // Destructor that prints the value of p_data and deallocates memory ~Example() { std::cout << *p_data << std::endl; delete p_data; } int* p_data; // Pointer to an integer }; int main() { Example obj1(25); // Creating an object with an initial value of 25 Example obj2(obj1); // Creating a second object using the obj1 *obj2.p_data = 1000; // Modifying the value of by p_data in the obj2 }

Note

It generates error: free(): double free detected

Shallow Copy
Deep Copy
Copies data values as they are, including pointers.Allocates separate memory and copies actual values.
Copies the address of the pointers directly.Creates a new memory location and copies the value pointed to.
Uses the same memory locations as the original.Allocates new memory locations for copied data.
Can lead to issues like double free.Prevents resource conflicts by creating separate copies.
Suitable for simple structures without dynamic memory allocation.Essential for objects with dynamic memory management.
Generally faster due to direct copying.Slower due to memory allocation and value copying.
Risky in managing resources, prone to errors.Safer, as it ensures independent copies of resources.

Note

That is precisely why a copy constructor is essential. It enables us to perform a deep copy, ensuring safety in the process.

Syntax of Copy Constructor

Creating a copy constructor shares some similarities with creating a constructor, yet it has its own distinctive features. The general approach to creating a copy constructor as usual is outlined below:

  • Name: the copy constructor has the same name as the class. It does not have any unique prefix or symbol to differentiate it from the regular constructor.
  • Parameter Type: it takes a single parameter, typically a reference to a constant object of the same class.
  • No Return Type: similar to other constructors and the destructor, the copy constructor does not have a return type, not even void.
  • Special Usage: it is called automatically by the compiler in specific scenarios, such as when an object is passed by value to a function, returned from a function, or initialized using another object of the same class.
cpp

main

copy
123456789101112131415161718192021222324252627
#include <iostream> class Example { public: // Constructor that initializes p_data with a new integer value Example(int data) : p_data(new int(data)) { } // Copy constructor that performs deep copy of the Example object Example(const Example& other) : p_data(new int(*other.p_data)) { } // Destructor that prints the value pointed to by p_data and deallocates memory ~Example() { std::cout << *p_data << std::endl; delete p_data; } int* p_data; // Pointer to an integer }; int main() { Example first_obj(25); // Creating an Example object with an initial value of 25 Example second_obj(first_obj); // Creating a obj2 using obj1 *second_obj.p_data = 1000; // Modifying the value pointed }

The Rule of Three

There is a guideline for classes that manage dynamically allocated memory or other resources. It states that if it needs to provide a custom implementation for any of the following three methods:

  1. Destructor (~Example()).
  2. Copy constructor (Example(const Example&)).
  3. Copy assignment operator (Example& operator=(const Example&)).

Then it often needs to provide implementations for all three of them. This is because if a class manages resources that require custom cleanup or copying behavior, the default implementations provided by the compiler may not be suitable.

1. What is the purpose of a copy constructor?
2. Which of the following describes a deep copy?
What is the purpose of a copy constructor?

What is the purpose of a copy constructor?

Selecciona la respuesta correcta

Which of the following describes a deep copy?

Which of the following describes a deep copy?

Selecciona unas respuestas correctas

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 2. Capítulo 8
some-alt