copy constructor (tsz. copy constructors)
A copy constructor egy speciális konstruktor a C++-ban, amely egy objektum másolatának létrehozására szolgál. A copy constructor akkor kerül meghívásra, amikor egy objektumot másolunk (például egy másik objektumból hozzuk létre), vagy amikor egy objektumot érték szerinti paraméterként adunk át egy függvénynek. A copy constructor feladata, hogy az objektum adatainak helyes másolatát hozza létre.
Ha nem definiálunk saját copy constructort, a C++ automatikusan generál egy alapértelmezett copy constructort, amely egy tag-on-tag másolás alapján működik. Ez az alapértelmezett copy constructor bitről bitre másolja az objektum adattagjait.
Az alapértelmezett copy constructor szintaxisa:
ClassName(const ClassName& other);
#include <iostream>
using namespace std;
class MyClass {
public:
int x;
// Konstruktor
MyClass(int val) : x(val) {}
// Copy constructor
MyClass(const MyClass& other) {
x = other.x;
cout << "Copy constructor meghívva." << endl;
}
};
int main() {
MyClass obj1(10); // Létrehozunk egy objektumot
MyClass obj2 = obj1; // Copy constructor hívódik meg
cout << "obj1.x = " << obj1.x << endl;
cout << "obj2.x = " << obj2.x << endl;
return 0;
}
Copy constructor meghívva. obj1.x = 10 obj2.x = 10
Magyarázat: - Az obj1
objektumot létrehozzuk, és értéket rendelünk neki. - Az obj2
objektumot az obj1
másolataként hozjuk létre. Ekkor a copy constructor hívódik meg, amely az obj1
értékét (10) átmásolja obj2
-be. - A copy constructor a másolt objektum adattagjait átadja az új objektumnak.
A saját copy constructor akkor válik szükségessé, ha az osztályunk olyan adatokat tartalmaz, amelyek dinamikusan foglalt memóriát használnak (például pointereket). Az alapértelmezett copy constructor csak bitről bitre másol, így ha az osztályunk tartalmaz olyan adatokat, amelyek saját memóriafoglalást igényelnek, akkor azt a saját copy constructorunkkal kell kezelnünk. Ez különösen akkor fontos, ha a deep copy (mély másolat) szükséges.
Ha az osztályunk pointereket tartalmaz, akkor az alapértelmezett copy constructor nem fog megfelelően működni, mert mindkét objektum ugyanarra a memóriaterületre fog mutatni, és ha az egyik objektumot töröljük, a másik is megsérülhet. Ilyenkor deep copy-ra van szükség, ami azt jelenti, hogy az adattagokat új memóriahelyekre másoljuk.
#include <iostream>
using namespace std;
class MyClass {
public:
int* data;
// Konstruktor
MyClass(int val) {
data = new int; // Dinamikus memóriafoglalás
*data = val;
}
// Copy constructor (Deep copy)
MyClass(const MyClass& other) {
data = new int; // Új memóriafoglalás
*data = *(other.data); // Másolás a másik objektumból
cout << "Copy constructor hívva (Deep copy)." << endl;
}
// Destruktor
~MyClass() {
delete data; // Dinamikus memória felszabadítása
}
};
int main() {
MyClass obj1(10); // Létrehozunk egy objektumot
MyClass obj2 = obj1; // Copy constructor hívódik meg (Deep copy)
cout << "*obj1.data = " << *obj1.data << endl;
cout << "*obj2.data = " << *obj2.data << endl;
return 0;
}
Copy constructor hívva (Deep copy). *obj1.data = 10 *obj2.data = 10
Magyarázat: - Az obj1
objektum egy dinamikusan foglalt int
adatot tartalmaz. - Az obj2
objektumot az obj1
másolataként hozzuk létre. A copy constructor itt deep copy-t végez: új memóriát foglal, és az adatot másolja. - Ez biztosítja, hogy obj1
és obj2
két különböző memóriaterületet használ, így ha az egyik objektumot töröljük, a másik nem lesz hatással.
A copy constructor akkor hívódik meg, ha:
MyClass obj2 = obj1;
).void f(MyClass obj)
).
Ha nem definiálunk saját copy constructort, a C++ automatikusan generál egyet, amely csak bitről bitre másolja az objektum adattagjait. Azonban, ha a típusunk olyan adatokat tartalmaz, amelyek dinamikusan foglalnak memóriát (pl. pointerek), akkor saját copy constructort kell definiálni, hogy elkerüljük a problémákat, mint a memória szivárgás vagy adatvesztés.
A move constructor (amely a C++11-ben került bevezetésre) egy olyan konstruktor, amely az erőforrásokat “mozgathatja” (másolás helyett) az egyik objektumból egy másikba, így elkerülhetjük a felesleges másolásokat. A move constructor a C++ újabb verzióiban válik szükségessé, ha a programban az objektumokat gyorsan szeretnénk áthelyezni (pl. egy vektorban).
A copy constructor kulcsfontosságú eszköz a C++-ban, hogy az objektumok helyes másolásáról gondoskodjunk. Az alapértelmezett copy constructor bitről bitre másolja az objektumokat, azonban ha az objektum dinamikusan foglalt memóriát használ (pl. pointereket), akkor saját copy constructorra van szükség, amely deep copy-t végez. A copy constructor különösen fontos lehet a memória kezelésekor, hogy elkerüljük a memória szivárgást és adatvesztést.