C++: Constructor, Copy Constructor and Assignment operator

Post on 18-Jan-2015

8.373 views 7 download

Tags:

description

 

Transcript of C++: Constructor, Copy Constructor and Assignment operator

C++ Constructors

Jussi PohjolainenTAMK University of Applied Sciences

Constructors

• Constructor is a “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

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

point.cpp#include "point.h"

Point::Point(int x, int y){ x_ = x; y_ = y;}

int Point::GetX(){ return x_;}

int Point::GetY(){ return y_;}

main.cpp#include <iostream>

#include ”point.h"

using namespace std;

int main()

{

Point p = Point(5,5);

cout << p.GetX() << endl;

return 0;

}

Default Constructor

• Default constructor is a constructor that can be called without parameters:

class Example {

public:

Example(int x=0, int y=0);

}

Initialization Lists

• Basic rule: initialize all class members in constructor

• Use initialization lists for initialization• Initialization list is more efficient than

assignment

Example of Initialization List#ifndef _POINT_H_#define _POINT_H_

class Point { private: int x_; int y_; public: Point(int x, int y);};

#endif

Example of Initialization List

#include "point.h"

Point::Point(int x, int y) : x_(x),

y_(y)

{

}

this - pointer

• this pointer is used as a pointer to the class object instance by the member function

• This pointer stores the address of the class instance

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;}

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

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;}

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;}

Usage?#ifndef _POINT_H_#define _POINT_H_

class Point { private: int x; int y; public:

void SetX(int x); void SetY(int y); };

#endif

Usage?

#include "point.h”

void Point::SetX(int x)

{

this->x = x;

}

void Point::SetY(int y)

{

this->y = y;

}

Destructors

• Destructor is a function that is called when the object is released from memory

• You cannot overload destructors– Class::~Class() { … }

COPY CONSTRUCTOR

Introduction

• What happens here?

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;

}

Copy Constructor

• A copy 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

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);

};

Default Copy Constructor#include "point.h”

Point::Point(const Point& p)

{

x_ = p.x_;

y_ = p.y_;

}

...

Default Copy Constructor#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;

}

Shallow Cloning Problem?class Line {

private:

Point* begin_;

Point* end_;

public:

Line(int x1, int y1, int x2, int y2);

Line(const Line& l);

~Line();

};

Shallow Cloning Problem?Line::Line(int x1, int y1, int x2, int y2) : begin(new Point(x1,y1)),

end(new Point(x2,y2))

{

}

Line::Line(const &Line l)

{

begin = l.begin;

end = l.end;

}

Line::~Line()

{

delete begin;

delete end;

}

Shallow Cloning Problem?

int main()

{

Line a(1,1,10,10);

Line b = a;

}

Implement your own Deep CloneLine::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);

}

Rules about Copy Constructors

• 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 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;

}

Assignment Operator#ifndef POINT#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

Point& Point::operator=(const Point& p)

{

x_ = p.x_;

y_ = p.y_;

return *this;

}

Assignment Operatorint main(){ 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;}

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?

Result:a.out(8992) malloc: *** error for object 0x100160: double free*** set a breakpoint in malloc_error_break to debug

WHY?

Why?

• A default assignment operator is used• Default assignment operator makes shallow

copy• Result is two persons with one heart…

Deep copyPerson& Person::operator=(Person& p) {

delete heart;

heart = new Heart();

heart->bloodAmount = p.heart->bloodAmount;

return *this;

}

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;

}

Correct Wayint main() { 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;}