constructors and destructors. constructor constructor—what’s this? constructor—what’s this?...
TRANSCRIPT
Constructors Constructors and Destructorsand Destructors
ConstructorConstructor
Constructor—Constructor—what’s this?what’s this? method used for initializing objects (of certain method used for initializing objects (of certain
class)class) a recipe for creating object of a given classa recipe for creating object of a given class
Constructor—Constructor—do we need it?do we need it? do the class variables need initialization?do the class variables need initialization?
Constructor—declaring Constructor—declaring For the T class:For the T class:
T(args);T(args); or or T::T(args);T::T(args);
class class pointpoint{{
double x, y;double x, y;public:public:
// …// …pointpoint(double, double);(double, double); // // no return value, even voidno return value, even voidpointpoint(double);(double); // overloadable// overloadablepointpoint();();
};};
Constructor—an unusual Constructor—an unusual methodmethod
We cannot not specify the return value (even: We cannot not specify the return value (even: no void).no void).
We cannot call it for the already constucted We cannot call it for the already constucted object.object.
We cannot get it’s address. We cannot get it’s address. It is not even visible in the class scope and has It is not even visible in the class scope and has
no name (according to ANSI).no name (according to ANSI).
Calling Calling Constructor with no args (default constructor):Constructor with no args (default constructor):
point p1;point p1;
Others:Others:
point p3(10.0, 20.0); point p3(10.0, 20.0); // 2 arg.// 2 arg.point p2(1.0);point p2(1.0); // 1 arg.// 1 arg.// point p1(); // point p1(); // this would be a call of p1 function// this would be a call of p1 function
point p2=1.0;point p2=1.0; // // this way 1 arg. c. onlythis way 1 arg. c. only
CallingCalling
we may specify which one to call we may specify which one to call
point p3=point(10.0, 20.0); point p3=point(10.0, 20.0); point p2=point(1.0); point p2=point(1.0); point p1=point();point p1=point();
or:or:
point p3=point::point(10.0, 20.0); point p3=point::point(10.0, 20.0); point p3=point::point(1.0); point p3=point::point(1.0); point p1=point::point();point p1=point::point();
Calling Calling annonymous objects annonymous objects
point pu;point pu; // not anonymous object pu// not anonymous object pupu = point (3);pu = point (3);
// temporary anonymous object, // temporary anonymous object, // it is deleted (right after assignment or// it is deleted (right after assignment or// later, „// later, „when not needed anymorewhen not needed anymore”)”)
point(20);point(20);// temporary anonymous and useless// temporary anonymous and useless
point * ppu;point * ppu;ppu=&point();ppu=&point();
// an error hard to trace, correct syntax// an error hard to trace, correct syntax
Defining Defining
class class pointpoint
{{
double x, y;double x, y;
public:public:
// …// …
pointpoint(double(double, double, double););
pointpoint(double);(double);
pointpoint()()
{{
x=y=0.0;x=y=0.0;
}};;
};};
inline point::pointinline point::point(double(double d d))
{{
x=y=d;x=y=d;
}}
point::pointpoint::point(double(double x0, x0,
double y0double y0))
{{
x=x0;x=x0;
y=y0;y=y0;
}}
Initialization listInitialization list in a definition of a constructorin a definition of a constructor ( (exclusivelly hereexclusivelly here) ) we may use we may use
the initialization listthe initialization list
T() T() :: member(initializer)member(initializer) [, member(initializer) …] { } [, member(initializer) …] { }
class class pointpoint{{
double x, y;double x, y;public:public:
// …// …
pointpoint()():x(0.0), y(0.0):x(0.0), y(0.0) {}; {};
};};
Initialization listInitialization list
inline point::point(double d)inline point::point(double d)
:x(d), y(d):x(d), y(d)
{{
// all done// all done
}}
point::point(double x, double y)point::point(double x, double y)
:x(x), y(y):x(x), y(y) // it is unambiguous !!!// it is unambiguous !!!
{{
// all done// all done
}}
Initialization listInitialization list
the only way of initializing const and reference the only way of initializing const and reference members.members.
in i.l. except the class members (declared in the very in i.l. except the class members (declared in the very class, and not inherited) we may class, and not inherited) we may also also define the way define the way of constructing virtual and direct base classes.of constructing virtual and direct base classes.
position on the i.l. is of no importance, initialization position on the i.l. is of no importance, initialization is performed in ais performed in a following order: base classes following order: base classes (virtual and then direct bases in order of declaration), (virtual and then direct bases in order of declaration), member variables in order of declaration, member variables in order of declaration, constructor’s body.constructor’s body.
Initialization listInitialization list
point::point(int x, int y)point::point(int x, int y):x(x), y(y) {}:x(x), y(y) {}; ; //OK.//OK.
inline point::point(int i) :x(i), y(x) {}inline point::point(int i) :x(i), y(x) {}; ; //OK. //OK.
inline point::point(int i) :y(x), x(i) {}inline point::point(int i) :y(x), x(i) {}; ; //OK.//OK.
// // point::point(int i) :y(i), x(y) {} — point::point(int i) :y(i), x(y) {} — oops !!!oops !!!
The default constructorThe default constructor if no constructor was declared, then comif no constructor was declared, then comppiler iler
generates the default constructor generates the default constructor (constructor (constructor with no with no argumentsarguments)) ofof an empty body, for T class: an empty body, for T class:
T::T()T::T(){{}}
if we declare any constructor (even constructor with if we declare any constructor (even constructor with args) then compiler does not generate the default args) then compiler does not generate the default constructor.constructor.
Order of constructor callingOrder of constructor calling
ConstructorsConstructors1.1. base class (classes in order of declaration)base class (classes in order of declaration)
2.2. class members in order of declarationclass members in order of declaration
3.3. constructor’s bodyconstructor’s body
Important: object class members (and base classes), Important: object class members (and base classes), if not initialized in the initialization list, are actually if not initialized in the initialization list, are actually initialized twice:initialized twice:
1.1. by the default constructor of their classby the default constructor of their class
2.2. in the body of constructor of object being createdin the body of constructor of object being created
An exampleAn example
class segmentclass segment{{
point p1;point p1;int number;int number;point p2;point p2;
};};
segment::segment()segment::segment() // what happens here ???// what happens here ??? :p1(1.0, 1.0):p1(1.0, 1.0){{
p2=point(1.0);p2=point(1.0);};};
An exampleAn example
class segmentclass segment{{
point p1;point p1;int number;int number;point p2;point p2;
};};
segment::segment() segment::segment() :p1(1.0, 1.0):p1(1.0, 1.0) // constr. p1 (2-arg), constr. p2 (default)// constr. p1 (2-arg), constr. p2 (default){{ // number not initialized// number not initialized
p2=point(1.0);p2=point(1.0); // constr. temp. (1 arg.), assignmemt// constr. temp. (1 arg.), assignmemt};}; // destr. temp.// destr. temp.
Copy constructorCopy constructor
it is for initializing objects using other objects of the it is for initializing objects using other objects of the same class, for the T class:same class, for the T class:
T::T(const T &); T::T(const T &);
parameter has to be a reference (otherwise temp. parameter has to be a reference (otherwise temp. object would be created, that should also be somehow object would be created, that should also be somehow initialized – with the copy constructorinitialized – with the copy constructor!!))
parameter should be const to permit to call the parameter should be const to permit to call the constructor with the const argumentconstructor with the const argument
Copy constructorCopy constructor
for example. c.c. of the point class:for example. c.c. of the point class:
point(const point & p) :x(p.x), y(p.y) {}point(const point & p) :x(p.x), y(p.y) {}
as a copy constructor as a copy constructor for class T for class T we may use other we may use other constructor that may be called with one argument of constructor that may be called with one argument of type &Ttype &T: :
point(const point &, int=7);point(const point &, int=7);
Compiler generated copy Compiler generated copy constructorconstructor
Compiler generates copy constructor if programmer Compiler generates copy constructor if programmer does not define does not define oneone (other (other constructors are not constructors are not importantimportant in this case in this case).).
Compiler generated copy constructor copies object Compiler generated copy constructor copies object field by field field by field (base classes and object members with their copy (base classes and object members with their copy
constructors – just like in case of initialization list it works constructors – just like in case of initialization list it works also when the class has const members)also when the class has const members)
for the point class: for the point class: point(const point & p) :x(p.x), y(p.y) {} point(const point & p) :x(p.x), y(p.y) {}
DestructorDestructor
What is the destructor?What is the destructor? Easy to guess Easy to guess
When do we need it?When do we need it? Even easierEven easier
DestructorDestructor
Destructor of the classDestructor of the class T T::~T~T();();
np.:np.:~point()~point() // no args, no ret. value// no args, no ret. value{{
cout << ”\ncout << ”\nit’s me, The Point it’s me, The Point (x:” (x:” << x << „ y:” << y<< x << „ y:” << y;; << << „) „) in a moment I’ll be The Late Pointin a moment I’ll be The Late Point”;”;
}}
DestructorDestructor
as opposed to constructor it is in the class as opposed to constructor it is in the class scopescope
we may call itwe may call it
destructor, if not defined by programmer, is destructor, if not defined by programmer, is generated by compilergenerated by compiler it has empty body, but …it has empty body, but …
Order of calling constructors and Order of calling constructors and destructorsdestructors
ConstructorsConstructors1.1. base class (classes in order of declaration)base class (classes in order of declaration)2.2. class members in order of declarationclass members in order of declaration3.3. constructor’s bodyconstructor’s body
Destructors – simply opposite orderDestructors – simply opposite order1.1. destructor’s bodydestructor’s body2.2. destructors of class members (order opposite to destructors of class members (order opposite to
decdeclalaration)ration)3.3. destructor of the base class (classes in order opposite to destructor of the base class (classes in order opposite to
decdecllaration)aration)
Order of calling constructors and Order of calling constructors and destructorsdestructors
objects dobjects deefined in blocks (local, automatic)fined in blocks (local, automatic) constructors are called when the definition is executed constructors are called when the definition is executed
(met)(met) destructors after leaving the block, order opposite to destructors after leaving the block, order opposite to
constructorsconstructors
global objects (static)global objects (static) constructors are called in an order of objects’ definitions, constructors are called in an order of objects’ definitions,
before calling the main() functionbefore calling the main() function destructors in order opposite to constructors, after destructors in order opposite to constructors, after
finishing main().finishing main().
Order of calling constructors and Order of calling constructors and destructorsdestructors
dynamic objectsdynamic objects are controlled by the are controlled by the programmer (new and delete).programmer (new and delete).
memory allocation and a constructor callmemory allocation and a constructor call:: when the operator new is executedwhen the operator new is executed
destructor and deallocation: deletedestructor and deallocation: delete
Constructing and destructing Constructing and destructing dynamic objectsdynamic objects
point *pp0=new point;point *pp0=new point;point *pp1=new point(1.0);point *pp1=new point(1.0);point *pp2=new point(10.0, 20.0);point *pp2=new point(10.0, 20.0);point *point *arrPointsarrPoints=new point[10];=new point[10];
//// array of 10 pointsarray of 10 points // initialized with the default constructor // initialized with the default constructor // in order of increasing addresses// in order of increasing addresses// // new T[] – calls only the default constructornew T[] – calls only the default constructor
delete pp1;delete pp1;delete pp2;delete pp2;delete pp0;delete pp0;delete [] delete [] arrPointsarrPoints; ;
ExampleExamplepoint global=777;point global=777;int f(int)int f(int) {{ segment o;segment o; }}
void main()void main() {{point local;point local;point *p_local;point *p_local;local=global;local=global;local=point(10,20);local=point(10,20); int a=f(1);int a=f(1);for (int i=0; i<2; i++)for (int i=0; i<2; i++) {{ point point in_blockin_block=local;=local; }}p_local = new point(1.0);p_local = new point(1.0);point local2(10,20);point local2(10,20);delete p_local;delete p_local;p_local = new point();p_local = new point();
}}
ExampleExamplepoint global=777;point global=777;int f(int)int f(int) {{ segment o;segment o; } } c4c4,, c5, d5 c5, d5,, d4 d4
cc11void main()void main() { {
point lopoint localcal;; c2c2point *p_lopoint *p_localcal;;lolocalcal=global;=global;lolocalcal=point(10,20);=point(10,20); c3, d3c3, d3int a=f(1);int a=f(1);for (int i=0; i<2; i++)for (int i=0; i<2; i++) {{ point point in_blockin_block=lo=localcal;; c6, i==1 c7c6, i==1 c7 }} d6, i==1 d7d6, i==1 d7p_lop_localcal = new point(1.0); = new point(1.0); c8c8point lopoint localcal2(10,20);2(10,20); c9c9delete p_lodelete p_localcal;; d8d8p_lop_localcal = new point(); = new point(); c10c10
}} d9d9,, d d22, , d1, ???10d1, ???10
ExampleExample define class: persondefine class: person
class personclass person{{ int int age;age; char *name,char *name, *lastName;*lastName;public:public: person(const char *name, const char *lastName, const int age);person(const char *name, const char *lastName, const int age); person(const person & o);person(const person & o); ~person();~person();};};
inline person::person(const char *name, const char *lastName, const int age)inline person::person(const char *name, const char *lastName, const int age) ::age(age)age(age){{ person::name=new char[strlen(name) + 1];person::name=new char[strlen(name) + 1]; strcpy(person::name, name);strcpy(person::name, name); person::lastName=new char[strlen(lastName) + 1];person::lastName=new char[strlen(lastName) + 1]; strcpy(person::lastName, lastName);strcpy(person::lastName, lastName);}}
inline person::person(const person & o)inline person::person(const person & o) :age(o.age), name(new char[strlen(o.name) + 1]), :age(o.age), name(new char[strlen(o.name) + 1]), lastName(new char[strlen(o.lastName) + 1])lastName(new char[strlen(o.lastName) + 1]){{ strcpy(name, o.name);strcpy(name, o.name); strcpy(lastName, o.lastName);strcpy(lastName, o.lastName);}}
ExampleExample
inline person::~person()inline person::~person(){{ delete delete [] [] name;name; delete delete [] [] lastName;lastName;}}
ExampleExample
ExampleExample define the queue class (FIFO queue of persons)define the queue class (FIFO queue of persons)
class queueclass queue{{ person **persons; person **persons; // array of pointers to persons in queue// array of pointers to persons in queue const const int int capacity;capacity; // queue capacity// queue capacity int length;int length; // number of persons currently in queue// number of persons currently in queuepublic:public: queue(int capacity);queue(int capacity); ~queue();~queue(); int insert(const person &o); int insert(const person &o); // 1-no more room, 0-inserted// 1-no more room, 0-inserted int collect(person &o); int collect(person &o); // 1-empty queue, 0-collected// 1-empty queue, 0-collected};};
queue::queue(int capacity)queue::queue(int capacity):capacity(capacity), length(0),:capacity(capacity), length(0),persons(new (person*) [capacity]) persons(new (person*) [capacity]) { { }}
queue::~queue()queue::~queue(){{ for (int i=0; i<length; i++)for (int i=0; i<length; i++) delete persons[i];delete persons[i]; // // elementselements delete [] persons;delete [] persons; // // arrayarray}}
ExampleExample
int queue::insert(const person &o)int queue::insert(const person &o){{ if (length==capacity)if (length==capacity) return 1;return 1; persons[length++]=new person(o);persons[length++]=new person(o); // copy the method’s arg.// copy the method’s arg. return 0;return 0;}}
ExampleExample
int queue::collect(person &o)int queue::collect(person &o){{ if (length==0)if (length==0) return 1;return 1;
o.~person(); o.~person(); // we do not know (yet)// we do not know (yet) o=*persons[0];o=*persons[0]; // how to overload the = operator// how to overload the = operator
length--;length--; for(int i=0; i<length; i++)for(int i=0; i<length; i++) persons[i]=persons[i+1];persons[i]=persons[i+1];
return 0;return 0;}}
ExampleExample
int queue::collect(person &o)int queue::collect(person &o){{ if (length==0)if (length==0) return 1;return 1;
o.~person(); o.~person(); // we do not know (yet)// we do not know (yet) o=*persons[0];o=*persons[0]; // how to overload the = operator// how to overload the = operator
length--;length--; for(int i=0; i<length; i++)for(int i=0; i<length; i++) persons[i]=persons[i+1];persons[i]=persons[i+1];
return 0;return 0;}}
// find the memory leak !!!// find the memory leak !!!
ExampleExample