C++: Constructor, Copy Constructor and Assignment operator
The document discusses various C++ constructors including default constructors, initialization lists, copy constructors, assignment operators, and destructors. It provides examples of how to properly implement these special member functions to avoid problems like shallow copying and double deletes.
Constructors Constructor isa “init function” that is called when an object is created C++ provides default constructor (= constructor with no parameters) Constructor has the same name than the class Constructor does not return anything Constructor usually initalizes class members
3.
point.h #ifndef _POINT_H_#define _POINT_H_ class Point { private: int x_; int y_; public: Point(int x, int y); int GetX(); int GetY(); }; #endif
main.cpp #include <iostream>#include ”point.h" using namespace std; int main() { Point p = Point(5,5); cout << p.GetX() << endl; return 0; }
6.
Default Constructor Defaultconstructor is a constructor that can be called without parameters: class Example { public: Example(int x=0, int y=0); }
7.
Initialization Lists Basicrule: initialize all class members in constructor Use initialization lists for initialization Initialization list is more efficient than assignment
8.
Example of InitializationList #ifndef _POINT_H_ #define _POINT_H_ class Point { private: int x_; int y_; public: Point(int x, int y); }; #endif
9.
Example of InitializationList #include "point.h" Point::Point(int x, int y) : x_(x), y_(y) { }
10.
this - pointerthis pointer is used as a pointer to the class object instance by the member function This pointer stores the address of the class instance
11.
Example about this #include <iostream> #include ”point.h" using namespace std; int main() { Point p = Point(5,5); cout << &p << endl; // prints 0xbffffa98 return 0; }
12.
Example about this #ifndef _POINT_H_ #define _POINT_H_ class Point { private: int x_; int y_; public: Point(int x, int y); void PrintAddress(); }; #endif
13.
Example about this #include "point.h" #include <iostream> using namespace std; Point::Point(int x, int y) : x_(x), y_(y) { } void Point::PrintAddress() { cout << this ; }
14.
Example about this #include <iostream> using namespace std; #include "point.h" int main() { Point a(5,5); cout << &a << endl; // 0xbffffa98 a.PrintAddress(); // 0xbffffa98 return 0; }
15.
Usage? #ifndef _POINT_H_#define _POINT_H_ class Point { private: int x ; int y ; public: void SetX(int x); void SetY(int y); }; #endif
Introduction What happenshere? int main() { Point a(5,5); Point b = a; b.SetX(10); cout << a.GetX() << ", " << a.GetY() << endl; cout << b.GetX() << ", " << b.GetY() << endl; return 0; }
20.
Copy Constructor Acopy constructor is called whenever a new variable is created from an object Point p(5,5); Point a = p; // Copy constructor call! Point b(p); // Copy constructor call! C++ creates default copy constructor automatically
21.
Default Copy Constructorclass Point { private: int x_; int y_; public: Point(int x, int y); Point(const Point& p); int GetX(); int GetY(); void SetX(int x); void SetY(int y); };
Implement your ownDeep Clone Line::Line(const &Line l) { int x1 = ( l.begin )->GetX(); int y1 = ( l.end )->GetY(); int x2 = ( l.begin )->GetX(); int y2 = ( l.end )->GetY(); begin = new Point(x1, y1); end = new Point(x2, y2); }
28.
Rules about CopyConstructors If shallow cloning is enough, do not implement copy constructor If you need deep copy, implement copy constructor Implement also destructor and assignment operator
Assignment? #include <iostream>using namespace std; #include "point.h" int main() { Point a(5,5); // Constructor Point b = a; // Copy Constructor b = a; // Assignment! b.SetX(10); cout << a.GetX() << ", " << a.GetY() << endl; cout << b.GetX() << ", " << b.GetY() << endl; return 0; }
31.
Assignment Operator #ifndefPOINT #define POINT class Point { private: int x_; int y_; public: Point(int x, int y); Point(const Point& p); Point& operator=(const Point& p); ~Point(); ... }; #endif
Assignment Operator intmain() { Point a(5,5); Point b(6,6); Point c(7,7); a = b; // <=> a.operator=(b); a = b = c; // <=> (a.operator=(b)).operator=(c); return 0; }
34.
class Heart {public: int bloodAmount; }; class Person { public: Heart* heart; Person(); ~Person(); }; Person::Person() { heart = new Heart(); } Person::~Person() { delete heart; } int main() { Person a; Person b; a = b; } Result: a.out(8992) malloc: *** error for object 0x100160: double free *** set a breakpoint in malloc_error_break to debug WHY?
35.
Why? A defaultassignment operator is used Default assignment operator makes shallow copy Result is two persons with one heart…
36.
Deep copy Person&Person::operator=(Person& p) { delete heart; heart = new Heart(); heart->bloodAmount = p.heart->bloodAmount; return *this; }
37.
What about now…int main() { Person a; a = a; } Person& Person::operator=(Person& p) { delete heart; heart = new Heart(); heart->bloodAmount = p.heart->bloodAmount; return *this; }
38.
Correct Way intmain() { Person a; a = a; } Person& Person::operator=(Person& p) { if(this == &p) return *this; delete heart; heart = new Heart(); heart->bloodAmount = p.heart->bloodAmount; return *this; }