29
1 159.234 159.234 LECTURE 11 LECTURE 11 Constructors and destructors Copy constructor Textbook: p. 156-166, 183

159.234 LECTURE 11

Embed Size (px)

DESCRIPTION

159.234 LECTURE 11. Constructors and destructors Copy constructor Textbook: p. 156-166, 183. Constructor. P oint :: P oint () : x(0), y(0){} P oint :: P oint ( int i , int j): x( i ), y(j) {} A default constructor may be created as a function having the same Class name that - PowerPoint PPT Presentation

Citation preview

Page 1: 159.234 LECTURE 11

1

159.234159.234 LECTURE 11LECTURE 11

Constructors and destructorsCopy constructorTextbook: p. 156-166, 183

Page 2: 159.234 LECTURE 11

2

PPoint::oint::PPoint() : x(0), y(0){}oint() : x(0), y(0){}

PPoint::oint::PPoint(int i, int j): x(i), y(j) {}oint(int i, int j): x(i), y(j) {}

A default constructor default constructor may be created as a function having the same Class name that

• does not have any argument, or • comes with arguments with default values set

Const and Reference data members can only be initialized using an initializer list

Constructor initializers are in fact the preferred way of setting values.

Constructor

Page 3: 159.234 LECTURE 11

3

It is possible to construct constructors with default arguments.

Example:

Default Constructor:PPoint::oint::PPoint() : x(0), y(0){}oint() : x(0), y(0){}

Default Argument Constructor:PPoint::oint::PPoint(int i=0,int j=0):x(i), y(j) {}oint(int i=0,int j=0):x(i), y(j) {}

However, the default argument constructor becomes a default constructor when called without any arguments. When both forms appear in a class, ambiguity arises when the following statement is issued:

Point p;Point p;

Constructors with Default Arguments

No arguments

Initializer list is not always declared at the class interface (See ch_stack.cpp for an example)

Page 4: 159.234 LECTURE 11

4

Calling the Constructor

Explicit Call

Implicit Call

PPoint p = Point(5, 10); oint p = Point(5, 10);

Point p(5, 10);Point p(5, 10);

Creates a Point object p and passes the values 5 and 10 to it

Short-hand method; looks better and easier to implement

Page 5: 159.234 LECTURE 11

5

What is wrong in the following code?What is wrong in the following code? #include <iostream>using namespace std;int main(){ int *p, *r; p = new int; *p=10; r = new int; *r=25; r = p; cout <<(*p)<<" "<<(*r);

delete p; cout << (*r)<<endl; delete r; // will cause double delete error

return 0;}

Memory Leak.cpp

Page 6: 159.234 LECTURE 11

6

Each class has exactly oneexactly one destructor

When an object is destroyed - the object’s destructor is called.

Destructors are used when the object contains pointers and new has been used to allocate memory to them.

If we don’t free that memory before the object disappears, then the memory will never be freed - a memory leak.

DestructorDestructor

Page 7: 159.234 LECTURE 11

7

class str {public: str(void); ~str();~str(); char *s;

};

str::str(void) { s = new char[128];}

str::~str() str::~str() { delete[] s;}

Destructors do not have return values, and cannot have arguments – not even void.

Destructor

The destructor function has the same name as the class with a ~ at the front.

Page 8: 159.234 LECTURE 11

8

Destructors are used to release any resources allocated by the object.

The most common example is when the constructor uses new, and the destructor uses delete.

Destructors are a "prepare to dieprepare to die" member function.

They are often abbreviated "dtordtor". Constructors are “ctorctor”.

Destructor

Page 9: 159.234 LECTURE 11

9

Destructor:

• called by the system for you when an object is destroyable (e.g. about to go out of scope)

• has the same name same name as the class;

• with a ~~ at the front;

• does not have return values;

• cannot have arguments.

Destructor

Page 10: 159.234 LECTURE 11

10

Constructors and destructors are called automatically.

The order in which they are called depends on the order in which execution enters and leaves the scope in which objects are instantiated and the type of storage for objects.

General rule:General rule: destructor calls are made in the reverse order of the constructor calls.

When are constructors/destructors called?

Page 11: 159.234 LECTURE 11

11

class C { public: C(int); //constructor ~C(); //destructor private: int data;

};

C::C(int value){ data = value; cout<<“\nCtor called: "<< data; }

C::~C(){ cout<<“\nDtor called: "<< data; }

Page 12: 159.234 LECTURE 11

12

void createFc();C one(1); //global object

int main(){ cout <<"Main starts here."<<endl; static C two(2); //local static object cout<<"After two(local static)in main."<<endl; createFc(); //function call}

void createFc(){ cout <<endl<<" FC STARTS HERE. "<<endl; C ten(77); //local object cout<< "LAST IN FC. "<<endl<<endl;}

Page 13: 159.234 LECTURE 11

13

Output:

Ctor called: 1Main starts here.Ctor called: 2After two (local static) in main.

FC STARTS HERE.Ctor called: 77LAST IN FC.

Dtor called: 77Dtor called: 2Dtor called: 1

global

Local static

Local

Constructor and Destructor Call.cpp

Page 14: 159.234 LECTURE 11

14

For stack objects defined:For stack objects defined: Constructors called:Constructors called:

In global scope

Destructor called:Destructor called:

Before any other function (including main)

When main terminates, or exit is called

Local objectsWhen the object enters scope.

When the object leaves scope

Static local objects Once, when the object enters scope the first time.

When main terminates, or exit is called

When are constructors/destructors called?

Page 15: 159.234 LECTURE 11

15

Objects can be passed as function arguments.

class StrStr{ public: Str(){ s = new char[128]; assert(s!=0);

//… } ~Str(){ delete[] s } void printprint(){ //...} private: char* s;};

void display( StrStr s);

Problems when passing objects:

Object as argument

Passing Object Using Call by Value.cpp

Page 16: 159.234 LECTURE 11

16

int main(){int main(){ StrStr a; a; a.a.print()print();; //...//... if (value > 100) {display(a);}if (value > 100) {display(a);} a.print();a.print();}}void display( void display( StrStr s){s. s){s.print()print();};}

Assume that the value stored in a was “aaaaaaaaaa”

Output:Data is aaaaaaaaaaData is aaaaaaaaaaData is ¿?A ¿?A aa

Problems when passing objects:

Page 17: 159.234 LECTURE 11

17

Problem:

The destructordestructor is called when display(a)display(a)finishes; It damages the original object aa.

How to solve it?

1. Use call by reference: voidvoid display(Str &s);display(Str &s); so no copying is done

OR

2. Write a copy constructorcopy constructor for the class which does a proper (deep) copy

Passing object using Call by Reference.cpp

Copy Constructor.cpp

Page 18: 159.234 LECTURE 11

18

If we pass an object as an argument to a function

SStr p;tr p; display(display(pp););

The object is copied to the called routine. The copy constructor of the class is called to perform the copy.

When the class does not provide its copy constructor the copy constructor provided by the system is used, but this is not appropriate for classes with pointer data members!

System copy constructor only does a shallow job!

Copy Constructor

Page 19: 159.234 LECTURE 11

19

The copy constructor has the form:

SStr::tr::SStr(const tr(const SStr &x)tr &x)

The original object is referred to by xx. SStrtr has to copy it into the new object.

SStr::tr::SStr(const tr(const SStr &x){tr &x){ s = new char[128];s = new char[128]; strcpy(s,x.s);strcpy(s,x.s);}}

This performs a deep copy.

A new string is created in the object, and the original string copied into it.

Copy Constructor

Page 20: 159.234 LECTURE 11

20

If we omit the copy constructor, or write our own one like this:

str::str(const str &x) {str::str(const str &x) { s = x.s;s = x.s;}}

Then we get a shallow copy.

s is set to be the same pointer as x.s -there is only one string, both objects point to it.

When using a shallow copy, it is important to know how many objects refer to the same memory location.Only when the last object is destroyed can that memory be freed safely.

Copy Constructor

Page 21: 159.234 LECTURE 11

21

The copy constructor is also called when a function returns a classreturns a class, and when an object is initialised with another objectinitialised with another object.

str s1;

str s2(s1); str *sp = new str(s2);

Copy Constructor

Page 22: 159.234 LECTURE 11

22

1. When a copy of an object is required, such as in call-by-value. SStr p;tr p; display(p);display(p);

2. When returningreturning an object by value from a function.

Point findMiddlePt ( Point p1,Point p2){Point findMiddlePt ( Point p1,Point p2){ Point temp ;Point temp ; //---do something//---do something

return temp;return temp;}}

3. When initializing an object to be a copy of another object of the same class.

Str x;Str x;//...other statements here

Str y(x);Str y(x); //y declared and initialized with xor

Str y = x;Str y = x; //y declared and initialized with x

When is a copy constructor called?SUMMARY

Page 23: 159.234 LECTURE 11

23

There is one final use for constructors – to convert between types.

class pointpoint {public: point(int i=0, int j=0) : x(i),y(j) {} ...};

This point constructor allows us to create objects like:point a; //x,y defaults so a = (0,0)point b(3); //y defaults so b = (3,0)point c(2,3); //no defaults so c = (2,3)

Constructor for Conversion

Page 24: 159.234 LECTURE 11

24

If in our code we write: a = 4;

at first sight, this appears to be wrong, a is a point and 4 is an integer.

However the compiler allows it, as the constructor can be used to do the conversion. The constructor tells the compiler how to create a point out of an integer.

Constructor for Conversion

Page 25: 159.234 LECTURE 11

25

If we do not want the constructor to be used in this fashion, then we need to use the keyword explicit

class pointpoint {public: explicit point(int i=0, int j=0) : x(i),y(j) {} ...};

Constructor for Conversion

See pr_char.cpp

See ch_stack.cpp

Page 26: 159.234 LECTURE 11

26

Sample Program: ch_stackSee ch_stack.cpp

99....210

sTop=-1Max_len=100

Data members

99....210 T

hT siStrStr

PushPush• Increment Top• Put character into element of stack pointed to by Top

Top

Initially,

Page 27: 159.234 LECTURE 11

27

#include <iostream>#include <cstring>#include <assert.h>using namespace std;void display( Str s); // prototype

class Str{ public: Str(char c = ' '){ p = new char[MAXLEN]; assert(p!=0); p[0] = c; p[1] = '\0'; } ~Str(){ delete[] p; }

Str( const Str &src ){ // copy constructor p = new char[MAXLEN]; // makes p point to another memory address assert( p != 0 ); strncpy( p, src.p, MAXLEN ); // do a deep copy of the string }

void print(){ cout << "Contents:" << p << endl;}

char* p; const static int MAXLEN = 128;};

void display( Str s){ // s is a partial (shallow) copy (has same internal p value) s.print(); // s is now freed up automaticaly - but this can damage (object a)}

int main(){ Str a('A'); // a now in scope a.print(); int value = 101; cerr << "Debug line 1" << endl; if (value > 100){ display(a); // passes a copy of a } cerr << "Debug line 2" << endl; a.print(); cerr << "Debug line 3" << endl; return 0;}

Example Output:Contents:ADebug line 1Contents:ADebug line 2Contents:ADebug line 3

Page 28: 159.234 LECTURE 11

28

A constructor constructs objects of its class type. This process may involve data members and allocating free store, using operator new.

A default constructor is a constructor requiring no arguments (initialising arrays).

A copy constructor is used to copy one value into another when:• a type variable is initialized by a type value;• a type value is passed as an argument to a function;• a type value is returned from a function.

A destructor “releases” any resources allocated by the object, typically by using delete.

Summary

Page 29: 159.234 LECTURE 11

29

Next: Friend functions/classes

Textbook: p.200-203