Nesnenin kopyalandığı durumlarda copy constructor çağrılıyor. Move constructor ise kopyalama işlemi yerine var olan nesneyi yeni nesneye atıyor. Yani bir nevi bir yer değiştirme durumu söz konusu oluyor.
Copy Constructor
- Nesne kopyalandığında çağrılır.
- Eğer biz yazmazsak, compiler bizim için bir tane yazar (tıpkı default constructor gibi).
- Genelde nesnenin shallow veya deep copy yapılma durumunu belirlemek için kullanılır. Diğer durumlarda zaten default constructor yeterli olacaktır.
Hangi durumlarda çağrılabilir:
- When an object of the class is returned by value.
- When an object of the class is passed (to a function) by value as an argument.
- When an object is constructed based on another object of the same class.
- When an object is constructed using initialization lists with braces
- When the compiler generates a temporary object.
https://www.geeksforgeeks.org/when-is-a-copy-constructor-called-in-cpp
Kısacası fonksiyonun pass by value ile parametre alması, fonksiyonun değer döndürmesi esnasında, var olan nesneden yeni bir nesne oluşturma durumunda bu constructor çağrılabilir. Neden kesin bir şey demiyorum çünkü compilerın optimize ettiği durumlar var, istisnalar var…
// main.cpp
#include <iostream>
using namespace std;
class Player {
std::string name;
int health;
public:
Player(std::string name = "NULL", int health = 0) : name{ name }, health{ health } {}
Player(const Player& player) : // copy constructor ...
Player{ player.name, player.health } // ... with delegation
{
cout << "Copy constructor called" << endl;
}
void print() {
cout << name << "\t" << health << endl;
}
};
Player func(Player p) { // Copy constructor called
p.print(); // NULL 0
return p; // Copy constructor called
}
int main() {
Player p1;
Player p2{ p1 }; // Copy constructor called
func(p2);
}Shallow & Deep Copy
- Shallow = sığ ; Deep = derin; anlamlarına gelir.
- Shallow copy de bellekte bulunan asıl veri kopyalanmaz! Sadece aynı veriyi işaret eden yeni bir referans oluşturur.
- Diğer tarafta deep copy de bellekte bulunan verinin tam anlamıyla yeni bir kopyası oluşturulur.
- Shallow copy durumunda herhangi bir kopya değiştirildiğinde tüm diğer kopyalar da değiştirilmiş olur.
- Deep copy de ise kopyalardan herhangi birinin değiştirilmesi diğerlerine etki etmez.
OOP ye girmeden daha basit bir kodla bunu anlatabiliriz:
// main.cpp
#include <iostream>
using namespace std;
void fill_arr(int* arr, int size = 10, int value = 0) {
for (int i{}; i < size; i++)
arr[i] = value;
}
void copy_arr(int* source_arr, int* destination_arr, int size = 10) {
for (int i{}; i < size; i++)
destination_arr[i] = source_arr[i];
}
void print_arr(int* arr, int size = 10) {
for (int i{}; i < size; i++)
cout << arr[i] << ", ";
cout << endl;
}
int main() {
// create and fill array
int arr_size = 10;
int* arr = new int[arr_size];
fill_arr(arr, arr_size, 5);
// shallow copy
int* shallow = arr;
// deep copy
int* deep = new int[arr_size];
copy_arr(arr, deep, arr_size);
print_arr(arr, arr_size); // 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
print_arr(shallow, arr_size); // 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
print_arr(deep, arr_size); // 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
fill_arr(arr, arr_size, 7);
print_arr(arr, arr_size); // 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
print_arr(shallow, arr_size); // 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
print_arr(deep, arr_size); // 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
}OOP’de de durum bundan farklı değil.

Leave a Reply