Upload
liberty-haley
View
31
Download
1
Tags:
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
1
159.234159.234 LECTURE 11LECTURE 11
Constructors and destructorsCopy constructorTextbook: p. 156-166, 183
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
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)
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
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
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
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.
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
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
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?
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; }
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;}
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
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?
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
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:
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
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
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
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
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
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
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
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
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
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,
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
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
29
Next: Friend functions/classes
Textbook: p.200-203