Constructors and Destructors in C++
Σύνθεζη Πνιύ ζπρλά ζηε C++ κία θιάζε κπνξεί λα πεξηέρεη ζαλ κέιεδεδνκέλα αληηθείκελα άιισλ θιάζεσλ. Πνηα είλαη ε ζεηξά κε ηελ νπνία δεκηνπξγνύληαη θαη θαηαζηξέθνληαη απηά ηα αληηθείκελα; Με πνηα ζεηξά θαινύληαη νη constructors θαη νη destructors ησλ θιάζεσλ; Πξώηα δεκηνπξγνύληαη ηα αληηθείκελα θαη θαιείηαη ν constructor ηεο εζσηεξηθήο θιάζεο θαη κεηά ηεο εμσηεξηθήο. Αληίζεηα, πξώηα θαιείηαη ν destructor ηεο εμσηεξηθήο θιάζεο θαη κεηά ηεο εζσηεξηθήο.
Παράδειγμα class Student Student() cout << "" << endl; ~Student() cout << " " << endl; ; class Classroom Student students[5]; Classroom() cout << "Creating a classroom!" << endl; ~Classroom() cout << "Destroying a classroom :( " << endl; ; class School Classroom classrooms[2]; School() cout << "Creating a school!" << endl; ~School() cout << "Destroying a school :( " << endl; ; int main() School *a_school = new School(); delete a_school; return 0;
Αποηέλεζμα Creating a classroom! Creating a classroom! Creating a school! Destroying a school :( Destroying a classroom :( Destroying a classroom :(
Δπλακηθή δέζκεπζε Σε πεξίπησζε πνπ κηα θιάζε έρεη ζαλ κέιε δεδνκέλα όρη αληηθείκελα θιάζεσλ αιιά δείθηεο ζε αληηθείκελα θιάζεσλ θαη θάλνπκε δπλακηθή δέζκεπζε ε ζεηξά ησλ εθηππώζεσλ ζα αιιάμεη δηόηη νη constructors ζα θιεζνύλ ηόηε πνπ γίλεηαη ε δέζκεπζε. Έηζη θαηά ηελ δεκηνπξγία/θαηαζηξνθή ηεο εμσηεξηθήο θιάζεο θαιείηαη ν δηθόο ηεο constructor/destructor, κέζα ζηνλ νπνίν είλαη δηθή καο επζύλε λα θαιέζνπκε ηνλ constructor/destructor ηεο εζσηεξηθήο θιάζεο κε ρξήζε new/delete.
Παράδειγμα class Student Student() cout << "" << endl; ~Student() cout << " " << endl; ; class Classroom Student *students; Classroom() students = new Student[5]; cout << "Creating a classroom!" << endl; ~Classroom() delete[] students; cout << "Destroying a classroom :( " << endl; ; class School Classroom *classrooms; School() classrooms = new Classroom[2]; cout << "Creating a school!" << endl; ~School() delete[] classrooms; cout << "Destroying a school :( " << endl; ; int main() School *a_school = new School(); delete a_school; return 0;
Αποηέλεζμα Creating a classroom! Creating a classroom! Creating a school! Destroying a classroom :( Destroying a classroom :( Destroying a school :(
Τν απνηέιεζκα κπνξεί επίζεο λα εμαξηάηαη από ην ζεκείν πνπ βάδνπκε ηηο εθηππώζεηο. Απηό δελ πξέπεη λα καο κπεξδεύεη.
Παράδειγμα class Student Student() cout << "" << endl; ~Student() cout << " " << endl; ; class Classroom Student *students; Classroom() cout << "Creating a classroom!" << endl; students = new Student[5]; ~Classroom() cout << "Destroying a classroom :( " << endl; delete[] students; ; class School Classroom *classrooms; School() cout << "Creating a school!" << endl; classrooms = new Classroom[2]; ~School() cout << "Destroying a school :( " << endl; delete[] classrooms; ; int main() School *a_school = new School(); delete a_school; return 0;
Αποηέλεζμα Creating a school! Creating a classroom! Creating a classroom! Destroying a school :( Destroying a classroom :( Destroying a classroom :(
Κληρονομικόηηηα Έλαο άιινο ηξόπνο ζύλδεζεο θιάζεσλ κεηαμύ ηνπο είλαη ε θιεξνλνκηθόηεηα. Καη ζε απηή ηελ πεξίπησζε πξώηα δεκηνπξγνύληαη ηα αληηθείκελα θαη θαιείηαη ν constructor ηεο parent/base θιάζεο θαη κεηά ηεο child/derived θιάζεο. Αληίζεηα, πξώηα θαιείηαη ν destructor ηεο child/derived θιάζεο θαη κεηά ηεο parent/base. Σε πεξίπησζε πνπ είηε ε base είηε ε child θιάζε έρνπλ αληηθείκελα θιάζεσλ σο data members (ζύλζεζε), ηζρύεη ε ζεηξά πνπ εηπώζεθε πξνεγνπκέλσο γηα ηελ ζύλζεζε.
Με άλλα λόγια: Construction: 1. Data members of base class 2. Base class 3. Data members of derived class 4. Derived class Destruction: 1. Derived class 2. Data members of derived class 3. Base class 4. Data members of base class
Παράδειγμα class Driver Driver() cout << "I am a driver!" << endl; ~Driver() cout << "Driver leaving..." << endl; ; class Passenger Passenger() cout << "I am a passenger!" << endl; ~Passenger() cout << "Passenger leaving..." << endl; ; int main() Car *car_p = new Car(); delete car_p; return 0; class Vehicle Passenger passenger; Vehicle() cout << "I am a vehicle!" << endl; ~Vehicle() cout << "Vehicle destroyed!" << endl; ; class Car: public Vehicle Driver driver; Car() cout << "I am a car!" << endl; ~Car() cout << "Car destroyed!" << endl; ;
Αποηέλεζμα I am a passenger! I am a vehicle! I am a driver! I am a car! Car destroyed! Driver leaving... Vehicle destroyed! Passenger leaving...
Ορίζμαηα by value Όηαλ κία ζπλάξηεζε παίξλεη σο όξηζκα έλα αληηθείκελν θαη όρη αλαθνξά ή δείθηε ζε αληηθείκελν, ηόηε κε ηελ θιήζε ηεο ζπλάξηεζεο απηόκαηα θαιείηαη ν copy-constructor ηεο θιάζεο ηνπ αληηθεηκέλνπ γηα λα αξρηθνπνηήζεη ην όξηζκα. Δειαδή, δεκηνπξγείηαη έλα αληίγξαθν ηνπ αληηθεηκέλνπ πνπ δόζεθε σο όξηζκα. Μέζα ζηε ζπλάξηεζε, αληί γηα ην ίδην ην αληηθείκελν πνπ δόζεθε σο όξηζκα, ρξεζηκνπνηείηαη ην αληίγξαθν πνπ δεκηνπξγήζεθε. Τν αληίγξαθν είλαη δειαδή κία ηνπηθή κεηαβιεηή θαη θαηαζηξέθεηαη κόιηο βγεη από ηελ εκβέιεηα ηεο ζπλάξηεζεο.
Όηαλ κία ζπλάξηεζε επηζηξέθεη (return) έλα αληηθείκελν, δεκηνπξγείηαη (πάιη κε ρξήζε copy constructor) θαη επηζηξέθεηαη έλα αληίγξαθν ηνπ αληηθεηκέλνπ. Απηό ην αληίγξαθν είλαη έλα πξνζσξηλό αληηθείκελν, ην νπνίν θαηαζηξέθεηαη, αθνύ πεξαζηνύλ ηα δεδνκέλα ηνπ ζηελ κεηαβιεηή πνπ ρξεζηκνπνηνύκε γηα λα απνζεθεύζνπκε ό,ηη καο επέζηξεςε ε ζπλάξηεζε. Δειαδή: Α function() A a; return a; Return Σην δηπιαλό παξάδεηγκα, θαηά ηελ επηζηξνθή από ηε ζπλάξηεζε θαιείηαη ν copy constructor πνπ δεκηνπξγεί έλα αληίγξαθν ηνπ a, ην νπνίν επηζηξέθεη ε ζπλάξηεζε function. Σηε ζπλέρεηα θαιείηαη assignment operator πνπ αλαζέηεη ηε ηηκή ηνπ αληίγξαθνπ ζηε κεηαβιεηή a1. Τέινο θαιείηαη ν destructor θαη θαηαζηξέθεη ην πξνζσξηλό αληίγξαθν ηνπ a πνπ δεκηνπξγήζεθε κε ηε return. A a1; a1 = function(); Α a2 = function(); Σηε πεξίπησζε πνπ ην επηζηξεθόκελν αληηθείκελν ρξεζηκνπνηείηαη γηα δεκηνπξγία νέου αληηθεηκέλνπ (a2) κε copy constructor, ζπλήζσο θαιείηαη κόλν έλαο copy constructor (return value optimization). Δηαθνξεηηθά ζα έπξεπε λα θιεζεί έλαο copy constructor κε ηε return, έλαο κε ηελ δεκηνπξγία ηνπ a2, θαη ηέινο ν destructor γηα λα θαηαζηξέςεη ην πξνζσξηλό αληίγξαθν ηνπ a πνπ δεκηνπξγήζεθε κε ηε return.
Παράδειγμα class A A() cout << "Constructor!" << endl; A(const A& a) cout << "Copy constructor!" << endl; A& operator=(const A& a) cout << "Assignment operator!" << endl; return *this; ~A() cout << "Destructor!" << endl; ; A function(a & a) return a; void function2(a a) cout << "Created a local variable!" << endl; int main() A a; A a1; cout << "Copy constructor, assignment operator, destructor!" << endl; a1 = function(a); cout << "Only one copy constructor this time!" << endl; A a2 = function(a); cout << "Passing argument by value!" << endl; function2(a); cout << "End of example!" << endl; return 0;
Αποηέλεζμα Constructor! Constructor! Copy constructor, assignment operator, destructor! Copy constructor! Assignment operator! Destructor! Only one copy constructor this time! Copy constructor! Passing argument by value! Copy constructor! Created a local variable! Destructor! End of example! Destructor! Destructor! Destructor!