C++ Copy Constructor
In this page:
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 <iostream>
class Point {
public:
int x;
Point(int val) : x(val) {}
Point(const Point &other) : x(other.x) {
std::cout << "Copy constructor called" << std::endl;
}
};
int main() {
Point p1(5);
Point p2 = p1;
std::cout << p2.x << std::endl;
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 <iostream>
class Point {
public:
int x;
Point(int val) : x(val) {}
Point(const Point &other) : x(other.x) {
std::cout << "Copied" << std::endl;
}
};
void showPoint(Point p) {
std::cout << p.x << std::endl;
}
int main() {
Point p(5);
showPoint(p);
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
Chapter Quiz — Complete all 14 topics to unlock
0/14 topics done
Complete these topics first: