C++ Copy Constructor
In this page:
class ClassName {
public:
ClassName(const ClassName &other) {
// copy each member from other
}
};
ClassName copy = original;
Default Copy Constructor
If you don't write a copy constructor yourself, the compiler automatically generates a default one that performs a shallow, member-by-member copy from the source object into the new one.
This works fine for simple data but becomes dangerous once a class owns a raw pointer.
Example: Default Copy Constructor
#include <iostream>
class Point {
public:
int x = 5;
};
int main() {
Point p1;
Point p2 = p1; // compiler-generated shallow member-by-member copy
std::cout << p2.x << std::endl;
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Defining Custom Copy Constructor
You can define your own copy constructor to control precisely how a new object is initialized from an existing one; it takes a reference to a const object of the same class as its parameter, which lets it read the source without risking (or needing) a copy of its own.
Example: Defining Custom Copy Constructor
// Include std::cout and std::cin
#include <iostream>
// Define the type Point
class Point {
// Members below can be accessed from outside the class
public:
int x;
Point(int val) : x(val) {}
Point(const Point &other) : x(other.x) {
// Print to the console with cout
std::cout << "Copy constructor called" << std::endl;
}
};
// Program execution starts in main()
int main() {
Point p1(5);
Point p2 = p1;
// Print to the console with cout
std::cout << p2.x << std::endl;
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Shallow Copy vs Deep Copy
A shallow copy duplicates a pointer's address, leaving both the original and the copy pointing at the exact same memory — dangerous, since deleting one will leave the other holding a dangling pointer.
A deep copy instead allocates fresh memory and duplicates the actual data, so each object owns its own independent copy.
Example: Shallow Copy vs Deep Copy
#include <iostream>
class Buffer {
public:
int *data;
Buffer(int val) { data = new int(val); }
Buffer(const Buffer &other) {
data = new int(*other.data); // deep copy: separate memory
}
~Buffer() { delete data; }
};
int main() {
Buffer b1(10);
Buffer b2 = b1;
std::cout << *b1.data << " " << *b2.data << std::endl;
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Copy Constructor in Function Calls
The copy constructor fires automatically whenever an object is passed by value into a function, or returned by value out of one, which is why passing large objects by value can be surprisingly expensive — every call triggers a full copy unless move semantics kick in instead.
Example: Copy Constructor in Function Calls
// Include std::cout and std::cin
#include <iostream>
// Define the type Point
class Point {
// Members below can be accessed from outside the class
public:
int x;
Point(int val) : x(val) {}
Point(const Point &other) : x(other.x) {
// Print to the console with cout
std::cout << "Copied" << std::endl;
}
};
void showPoint(Point p) {
// Print to the console with cout
std::cout << p.x << std::endl;
}
// Program execution starts in main()
int main() {
Point p(5);
showPoint(p);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Preventing Object Copying
You can prevent a class's objects from ever being copied at all by explicitly deleting the copy constructor with '= delete'.
This is the standard technique used by types like std::unique_ptr, which are designed to have exactly one owner and must never be duplicated.
Example: Preventing Object Copying
#include <iostream>
class Resource {
public:
Resource() {}
Resource(const Resource &) = delete;
};
int main() {
Resource r1;
// Resource r2 = r1; would fail to compile: copy constructor deleted
std::cout << "Resource created, copying disabled" << std::endl;
return 0;
}
Login to try C/C++/Java/PHP code in the editor
- Relying on the default copy constructor with raw pointers, giving shallow copies and double delete.
- Writing
Obj(Obj other)instead ofObj(const Obj& other). - Forgetting to define a copy assignment operator along with the copy constructor.
Chapter Quiz — Complete all 14 topics to unlock
0/14 topics done
Complete these topics first: