You are on page 1of 25

Module 13

Intructors: Abir
Das and
Sourangshu
Bhattacharya
Module 13: Programming in C++
Objectives & Constructors, Destructors & Object Lifetime
Outline

Constructor
Contrasting with
Member Functions
Parameterized Intructors: Abir Das and Sourangshu Bhattacharya
Default Parameters
Overloaded

Destructor Department of Computer Science and Engineering


Contrasting with Indian Institute of Technology, Kharagpur
Member Functions

Default {abir, sourangshu}@cse.iitkgp.ac.in


Constructor

Object Lifetime
Automatic Slides taken from NPTEL course on Programming in Modern C++
Static
Dynamic by Prof. Partha Pratim Das
Module Summary

CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 1


Module Objectives

Module 13

Intructors: Abir • Understand Object Construction (Initialization)


Das and
Sourangshu
Bhattacharya
• Understand Object Destruction (De-Initialization)
Objectives &
• Understand Object Lifetime
Outline

Constructor
Contrasting with
Member Functions
Parameterized
Default Parameters
Overloaded

Destructor
Contrasting with
Member Functions

Default
Constructor

Object Lifetime
Automatic
Static
Dynamic

Module Summary

CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 2


Module Outline

Module 13

Intructors: Abir
1 Constructor
Das and
Sourangshu Contrasting with Member Functions
Bhattacharya
Parameterized
Objectives & Default Parameters
Outline
Overloaded
Constructor
Contrasting with
Member Functions 2 Destructor
Parameterized
Default Parameters
Contrasting with Member Functions
Overloaded

Destructor
3 Default Constructor
Contrasting with
Member Functions
4 Object Lifetime
Default
Constructor Automatic
Object Lifetime Static
Automatic
Static
Dynamic
Dynamic

Module Summary
5 Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 3
Program 13.01/02: Stack: Initialization

Module 13 Public Data Private Data

Intructors: Abir #include <iostream> #include <iostream>


Das and using namespace std; using namespace std;
Sourangshu
Bhattacharya class Stack { public: // VULNERABLE DATA class Stack { private: // PROTECTED DATA
char data_[10]; int top_; char data_[10]; int top_;
Objectives & public: public:
Outline void init() { top_ = -1; }
Constructor
int empty() { return (top_ == -1); } int empty() { return (top_ == -1); }
Contrasting with
void push(char x) { data_[++top_] = x; } void push(char x) { data_[++top_] = x; }
Member Functions void pop() { --top_; } void pop() { --top_; }
Parameterized char top() { return data_[top_]; } char top() { return data_[top_]; }
Default Parameters
}; };
Overloaded
int main() { char str[10] = "ABCDE"; int main() { char str[10] = "ABCDE";
Destructor Stack s; s.top_ = -1; // Exposed initialization Stack s; s.init(); // Clean initialization
Contrasting with
Member Functions
for (int i = 0; i < 5; ++i) s.push(str[i]); for (int i = 0; i < 5; ++i) s.push(str[i]);
Default // s.top_ = 2; // RISK - CORRUPTS STACK // s.top_ = 2; // Compile error - SAFE
Constructor
while (!s.empty()) { cout << s.top(); s.pop(); } while (!s.empty()) { cout << s.top(); s.pop(); }
Object Lifetime } }
Automatic
Static • Spills data structure codes into application • No code in application, but init() to be called
Dynamic • public data reveals the internals • private data protects the internals
Module Summary • To switch container, application needs to change • Switching container is seamless
• Application may corrupt the stack! • Application cannot corrupt the stack
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 4
Program 13.02/03: Stack: Initialization

Module 13 Using init() Using Constructor

Intructors: Abir #include <iostream> #include <iostream>


Das and using namespace std; using namespace std;
Sourangshu
Bhattacharya class Stack { private: // PROTECTED DATA class Stack { private: // PROTECTED DATA
char data_[10]; int top_; char data_[10]; int top_;
Objectives & public: void init() { top_ = -1; } public: Stack() : top_(-1) { } // Initialization
Outline int empty() { return (top_ == -1); } int empty() { return (top_ == -1); }
Constructor
void push(char x) { data_[++top_] = x; } void push(char x) { data_[++top_] = x; }
Contrasting with
void pop() { --top_; } void pop() { --top_; }
Member Functions char top() { return data_[top_]; } char top() { return data_[top_]; }
Parameterized }; };
Default Parameters
int main() { char str[10] = "ABCDE"; int main() { char str[10] = "ABCDE";
Overloaded
Stack s; s.init(); // Clean initialization Stack s; // Init by Stack::Stack() call
Destructor
Contrasting with for (int i = 0; i < 5; ++i) s.push(str[i]); for (int i = 0; i < 5; ++i) s.push(str[i]);
Member Functions
// s.top_ = 2; // Compile error - SAFE
Default while(!s.empty()) { cout << s.top(); s.pop(); } while(!s.empty()) { cout << s.top(); s.pop(); }
Constructor
} }
Object Lifetime
Automatic
Static • init() serves no visible purpose – application may forget • Can initialization be made a part of instantiation?
Dynamic to call
Module Summary
• If application misses to call init(), we have a corrupt stack • Yes. Constructor is implicitly called at instantiation as set
by the compiler
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 5
Program 13.04/05: Stack: Constructor

Module 13 Automatic Array Dynamic Array

Intructors: Abir #include <iostream> #include <iostream>


Das and using namespace std; using namespace std;
Sourangshu
Bhattacharya class Stack { private: class Stack { private:
char data_[10]; int top_; // Automatic char *data_; int top_; // Dynamic
Objectives & public: Stack(); // Constructor public: Stack(); // Constructor
Outline // More Stack methods // More Stack methods
Constructor
}; };
Contrasting with
Stack::Stack(): // Initialization List Stack::Stack(): data_(new char[10]), // Init List
Member Functions top_(-1) { cout << "Stack::Stack()" << endl; top_(-1) { cout << "Stack::Stack()" << endl;
Parameterized } }
Default Parameters
int main() { char str[10] = "ABCDE"; int main() { char str[10] = "ABCDE";
Overloaded
Stack s; // Init by Stack::Stack() call Stack s; // Init by Stack::Stack() call
Destructor for (int i=0; i<5; ++i) s.push(str[i]); for (int i=0; i<5; ++i) s.push(str[i]);
Contrasting with while(!s.empty()) { cout << s.top(); s.pop(); } while(!s.empty()) { cout << s.top(); s.pop(); }
Member Functions
} }
Default ----- -----
Constructor
Stack::Stack() Stack::Stack()
Object Lifetime EDCBA EDCBA
Automatic
Static
Dynamic • top initialized to -1 in initialization list • top initialized to -1 in initialization list
Module Summary
• data [10] initialized by default (automatic) • data initialized to new char[10] in init list
• Stack::Stack() called automatically when control passes Stack s; – Guarantees initialization
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 6
Constructor: Contrasting with Member Functions

Module 13 Constructor Member Function

Intructors: Abir • Is a static member function without this pointer – but gets • Has implicit this pointer
Das and
Sourangshu
the pointer to the memory where the object is constructed
Bhattacharya • Name is same as the name of the class • Any name different from name of class
class Stack { public: Stack(); }; class Stack { public: int empty(); };
Objectives &
Outline • Has no return type - not even void • Must have a return type - may be void
Constructor Stack::Stack(); // Not even void int Stack::empty();
Contrasting with • Does not return anything. Has no return statement • Must have at least one return statement
Member Functions
Parameterized
Stack::Stack(): top_(-1) int Stack::empty() { return (top_ == -1); }
Default Parameters { } // Returns implicitly void pop()
Overloaded { --top_; } // Implicit return for void
Destructor • Initializer list to initialize the data members • Not applicable
Contrasting with Stack::Stack(): // Initializer list
Member Functions
data_(new char[10]), // Init data_
Default top_(-1) // Init top_
Constructor
{ }
Object Lifetime
• Implicit call by instantiation / operator new • Explicit call by the object
Automatic
Static
Stack s; // Calls Stack::Stack() s.empty(); // Calls Stack::empty(&s)
Dynamic • May be public or private • May be public or private
Module Summary • May have any number of parameters • May have any number of parameters
• Can be overloaded • Can be overloaded
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 7
Program 13.06: Complex: Parameterized Constructor

Module 13 #include <iostream>


#include <cmath>
Intructors: Abir
Das and
using namespace std;
Sourangshu
Bhattacharya class Complex { private: double re_, im_;
public:
Objectives & Complex(double re, double im): // Constructor with parameters
Outline
re_(re), im_(im) // Initializer List: Parameters to initialize data members
Constructor { }
Contrasting with double norm() { return sqrt(re_*re_ + im_*im_); }
Member Functions
void print() {
Parameterized
Default Parameters
cout << "|" << re_ << "+j" << im_ << "| = ";
Overloaded
cout << norm() << endl;
}
Destructor
};
Contrasting with
Member Functions
int main() { Complex c(4.2, 5.3), // Complex::Complex(4.2, 5.3)
d(1.6, 2.9); // Complex::Complex(1.6, 2.9)
Default
Constructor
c.print();
Object Lifetime
d.print();
Automatic
}
Static
-----
Dynamic
|4.2+j5.3| = 6.7624
Module Summary |1.6+j2.9| = 3.3121
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 8
Program 13.07: Complex: Constructor with default parameters

Module 13 #include <iostream>


Intructors: Abir
#include <cmath>
Das and using namespace std;
Sourangshu
Bhattacharya
class Complex { private: double re_, im_; public:
Complex(double re = 0.0, double im = 0.0) : // Constructor with default parameters
Objectives &
Outline re_(re), im_(im) // Initializer List: Parameters to initialize data members
{ }
Constructor
double norm() { return sqrt(re_*re_ + im_*im_); }
Contrasting with
Member Functions void print() { cout << "|" << re_ << "+j" << im_ << "| = " << norm() << endl; }
Parameterized };
Default Parameters int main() {
Overloaded Complex c1(4.2, 5.3), // Complex::Complex(4.2, 5.3) -- both parameters explicit
Destructor
c2(4.2), // Complex::Complex(4.2, 0.0) -- second parameter default
Contrasting with
c3; // Complex::Complex(0.0, 0.0) -- both parameters default
Member Functions

Default c1.print();
Constructor c2.print();
Object Lifetime
c3.print();
Automatic
}
Static -----
Dynamic |4.2+j5.3| = 6.7624
|4.2+j0| = 4.2
Module Summary
|0+j0| = 0
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 9
Program 13.08: Stack: Constructor with default parameters

Module 13 #include <iostream>


#include <cstring>
Intructors: Abir
Das and
using namespace std;
Sourangshu
Bhattacharya class Stack { private: char *data_; int top_;
public: Stack(size_t = 10); // Size of data_ defaulted
Objectives & ~Stack() { delete data_[]; }
Outline
int empty() { return (top_ == -1); }
Constructor void push(char x) { data_[++top_] = x; }
Contrasting with void pop() { --top_; }
Member Functions
char top() { return data_[top_]; }
Parameterized
Default Parameters
};
Overloaded
Stack::Stack(size_t s) : data_(new char[s]), top_(-1) // Array of size s allocated and set to data_
{ cout << "Stack created with max size = " << s << endl; }
Destructor
Contrasting with
Member Functions
int main() { char str[] = "ABCDE"; int len = strlen(str);
Stack s(len); // Create a stack large enough for the problem
Default
Constructor
for (int i = 0; i < len; ++i) s.push(str[i]);
Object Lifetime
while (!s.empty()) { cout << s.top(); s.pop(); }
Automatic
}
Static
-----
Dynamic
Stack created with max size = 5
Module Summary EDCBA
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 10
Program 13.09: Complex: Overloaded Constructors
#include <iostream>
Module 13
#include <cmath>
Intructors: Abir using namespace std;
Das and
Sourangshu
Bhattacharya class Complex { private: double re_, im_; public:
Complex(double re, double im): re_(re), im_(im) { } // Two parameters
Objectives & Complex(double re): re_(re), im_(0.0) { } // One parameter
Outline Complex(): re_(0.0), im_(0.0) { } // No parameter
Constructor
Contrasting with
double norm() { return sqrt(re_*re_ + im_*im_); }
Member Functions void print() { cout << "|" << re_ << "+j" << im_ << "| = " << norm() << endl; }
Parameterized };
Default Parameters int main() {
Overloaded
Complex c1(4.2, 5.3), // Complex::Complex(double, double)
Destructor c2(4.2), // Complex::Complex(double)
Contrasting with c3; // Complex::Complex()
Member Functions

Default c1.print();
Constructor
c2.print();
Object Lifetime c3.print();
Automatic }
Static -----
Dynamic |4.2+j5.3| = 6.7624
Module Summary |4.2+j0| = 4.2
|0+j0| = 0
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 11
Program 13.10: Rect: Overloaded Constructors
#include <iostream>
Module 13
using namespace std;
Intructors: Abir
Das and class Pt { public: int x_, y_; Pt(int x, int y): x_(x), y_(y) { } }; // A Point
Sourangshu
Bhattacharya class Rect { Pt LT_, RB_; public:
Rect(Pt lt, Pt rb):
Objectives & LT_(lt), RB_(rb) { } // Cons 1: Points Left-Top lt and Right-Bottom rb
Outline Rect(Pt lt, int h, int w):
Constructor
LT_(lt), RB_(Pt(lt.x_+w, lt.y_+h)) { } // Cons 2: Point Left-Top lt, height h & width w
Contrasting with
Rect(int h, int w):
Member Functions LT_(Pt(0, 0)), RB_(Pt(w, h)) { } // Cons 3: height h, width w & Point origin as Left-Top
Parameterized int area() { return (RB_.x_-LT_.x_) * (RB_.y_-LT_.y_); }
Default Parameters };
Overloaded
int main() { Pt p1(2, 5), p2(8, 10);
Destructor Rect r1(p1, p2), // Cons 1: Rect::Rect(Pt, Pt)
Contrasting with r2(p1, 5, 6), // Cons 2: Rect::Rect(Pt, int, int)
Member Functions
r3(5, 6); // Cons 3: Rect::Rect(int, int)
Default cout << "Area of r1 = " << r1.area() << endl;
Constructor
cout << "Area of r2 = " << r2.area() << endl;
Object Lifetime cout << "Area of r3 = " << r3.area() << endl;
Automatic }
Static -----
Dynamic Area of r1 = 30
Module Summary Area of r2 = 30
Area of r3 = 30
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 12
Program 13.11/12: Stack: Destructor

Module 13 Resource Release by User Automatic Resource Release

Intructors: Abir #include <iostream> #include <iostream>


Das and using namespace std; using namespace std;
Sourangshu
Bhattacharya class Stack { char *data_; int top_; // Dynamic class Stack { char *data_; int top_; // Dynamic
public: Stack(): data_(new char[10]), top_(-1) public: Stack(): data_(new char[10]), top_(-1)
Objectives & { cout << "Stack() called\n"; } // Constructor { cout << "Stack() called\n"; } // Constructor
Outline void de_init() { delete [] data_; } ~Stack() { cout << "\n~Stack() called\n";
Constructor
delete [] data_; // Destructor
Contrasting with
}
Member Functions // More Stack methods // More Stack methods
Parameterized }; };
Default Parameters
int main() { char str[10] = "ABCDE"; int main() { char str[10] = "ABCDE";
Overloaded
Stack s; // Init by Stack::Stack() call Stack s; // Init by Stack::Stack() call
Destructor // Reverse string using Stack // Reverse string using Stack
Contrasting with s.de_init();
Member Functions
} } // De-Init by automatic Stack::~Stack() call
Default ----- -----
Constructor
Stack() called Stack() called
Object Lifetime EDCBA EDCBA
Automatic ~Stack() called
Static
Dynamic

Module Summary
• data leaks unless released within the scope of s • Can de-initialization be a part of scope rules?
• When to call de init()? User may forget to call • Yes. Destructor is implicitly called at end of scope
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 13
Destructor: Contrasting with Member Functions

Module 13
Destructor Member Function
Intructors: Abir
Das and
• Has implicit this pointer
• Has implicit this pointer
Sourangshu
Bhattacharya • Any name different from name of class
• Name is ˜ followed by the name of the class
class Stack { public:
Objectives & class Stack { public: int empty();
Outline ~Stack(); };
};
Constructor
• Must have a return type - may be void
Contrasting with
Member Functions
• Has no return type - not even void
int Stack::empty();
Stack::~Stack(); // Not even void
Parameterized
Default Parameters
• Does not return anything. Has no return statement
• Must have at least one return statement
Overloaded int Stack::empty()
Stack::~Stack() { return (top_ == -1); }
Destructor { } // Returns implicitly
Contrasting with • Explicit call by the object
Member Functions • Implicitly called at end of scope
s.empty(); // Calls Stack::empty(&s)
Default
Constructor
• May be public or private
• May be public or private
Object Lifetime
• No parameter is allowed - unique for the class
• May have any number of parameters
Automatic • Cannot be overloaded
• Can be overloaded
Static
Dynamic

Module Summary

CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 14


Default Constructor / Destructor

Module 13
• Constructor
Intructors: Abir
Das and
Sourangshu
◦ A constructor with no parameter is called a Default Constructor
Bhattacharya ◦ If no constructor is provided by the user, the compiler supplies a free default
Objectives & constructor
Outline
◦ Compiler-provided (free default) constructor, understandably, cannot initialize the
Constructor
Contrasting with
object to proper values. It has no code in its body
Member Functions
Parameterized • Destructor
Default Parameters
Overloaded ◦ If no destructor is provided by the user, the compiler supplies a free default
Destructor destructor
Contrasting with
Member Functions ◦ Compiler-provided (free default) destructor has no code in its body
Default
Constructor

Object Lifetime
Automatic
Static
Dynamic

Module Summary

CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 15


Program 13.13: Complex: Default Constructor: User Defined
#include <iostream>
Module 13
#include <cmath>
Intructors: Abir using namespace std;
Das and
Sourangshu
Bhattacharya class Complex { private: double re_, im_; public:
Complex(): re_(0.0), im_(0.0) // Default Constructor having no parameter
Objectives & { cout << "Ctor: (" << re_ << ", " << im_ << ")" << endl; }
Outline ~Complex() { cout << "Dtor: (" << re_ << ", " << im_ << ")" << endl; } // Destructor
Constructor
double norm() { return sqrt(re_*re_ + im_*im_); }
Contrasting with
void print() { cout << "|" << re_ << "+j" << im_ << "| = " << norm() << endl; }
Member Functions void set(double re, double im) { re_ = re; im_ = im; }
Parameterized };
Default Parameters int main() { Complex c; // Default constructor -- user provided
Overloaded
c.print(); // Print initial values
Destructor c.set(4.2, 5.3); // Set components
Contrasting with c.print(); // Print values set
Member Functions
} // Destuctor
Default -----
Constructor
Ctor: (0, 0)
Object Lifetime |0+j0| = 0
Automatic |4.2+j5.3| = 6.7624
Static Dtor: (4.2, 5.3)
Dynamic

Module Summary
• User has provided a default constructor
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 16
Program 13.14: Complex: Default Constructor: Free
#include <iostream>
Module 13
#include <cmath>
Intructors: Abir using namespace std;
Das and
Sourangshu
Bhattacharya class Complex { private: double re_, im_; // private data
public: // No constructor given be user. So compiler provides a free default one
Objectives & double norm() { return sqrt(re_*re_ + im_*im_); }
Outline void print() { cout << "|" << re_ << "+j" << im_ << "| = " << norm() << endl; }
Constructor
void set(double re, double im) { re_ = re; im_ = im; }
Contrasting with
};
Member Functions int main() { Complex c; // Free constructor from compiler. Initialization with garbage
Parameterized
Default Parameters c.print(); // Print initial value - garbage
Overloaded
c.set(4.2, 5.3); // Set proper components
Destructor c.print(); // Print values set
Contrasting with } // Free destuctor from compiler
Member Functions
-----
Default |-9.25596e+061+j-9.25596e+061| = 1.30899e+062
Constructor
|4.2+j5.3| = 6.7624
Object Lifetime
Automatic
Static • User has provided no constructor / destructor
Dynamic • Compiler provides default (free) constructor / destructor
Module Summary
• Compiler-provided constructor does nothing – components have garbage values
• Compiler-provided destructor does nothing
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 17
Object Lifetime

Module 13
• In OOP, the object lifetime (or life cycle) of an object is the time between an object’s
Intructors: Abir
Das and
creation and its destruction
Sourangshu
Bhattacharya
• Rules for object lifetime vary significantly:
◦ Between languages
Objectives &
Outline ◦ in some cases between implementations of a given language, and
Constructor ◦ lifetime of a particular object may vary from one run of the program to another
Contrasting with
Member Functions • Context C++: Object Llifetime coincides with Variable Lifetime (the extent of a
Parameterized
Default Parameters
variable when in a program’s execution the variable has a meaningful value) of a
Overloaded
variable with that object as value (both for static variables and automatic variables).
Destructor
Contrasting with
However, in general, object lifetime may not be tied to the lifetime of any one variable
Member Functions
• Context Java / Python: In OO languages that use garbage collection (GC), objects
Default
Constructor are allocated on the heap
Object Lifetime ◦ object lifetime is not determined by the lifetime of a given variable
Automatic
Static
◦ the value of a variable holding an object actually corresponds to a reference to the object,
Dynamic not the object itself, and
Module Summary ◦ destruction of the variable just destroys the reference, not the underlying object
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 18
Object Lifetime: When is an Object ready?
How long can it be used?
Application Class Code
Module 13

Intructors: Abir void MyFunc() { // E1: Allocation of c on Stack Complex::Complex(double re = 0.0, // Constructor
Das and ...
Sourangshu
double im = 0.0):
Bhattacharya Complex c; // E2: Constructor called re_(re), im_(im) // E3: Initialization
... { // E4: Object Lifetime STARTS with initialization
Objectives & cout << "Ctor:" << endl;
Outline c.norm(); // E5: Use }
Constructor
... double Complex::norm() // E6 norm executes
Contrasting with { return sqrt(re_*re_ + im_*im_); }
Member Functions return; // E7: Destructor called Complex::~Complex() { cout << "Dtor:" << endl;
Parameterized } // E9: De-Allocation of c from Stack } // E8: Object Lifetime ENDS with destructor
Default Parameters
Overloaded

Destructor Event Sequence and Object Lifetime


Contrasting with E1 MyFunc called. Stackframe allocated. c is a part of Stackframe
Member Functions
E2 Control to pass to Complex c. Ctor Complex::Complex(&c) called with the address of c on the frame
Default E3 Control on Initializer list of Complex::Complex(). Data members initialized (constructed)
Constructor
E4 Object Lifetime STARTS for c. Control reaches the start of the body of Constructor. Constructor executes
Object Lifetime E5 Control at c.norm(). Complex::norm(&c) called. Object is being used
Automatic
E6 Complex::norm() executes
Static
E7 Control to pass return in MyFunc. Desturctor Complex::~Complex(&c) called
Dynamic
E8 Destructor executes. Control reaches the end of the body of Destructor. Object Lifetime ENDS for c
Module Summary
E9 return executes. Stackframe including c de-allocated. Control returns to caller
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 19
Object Lifetime

Module 13
• Execution Stages
Intructors: Abir
Das and ◦ Memory Allocation and Binding
Sourangshu
Bhattacharya
◦ Constructor Call and Execution
◦ Object Use
Objectives &
Outline
◦ Destructor Call and Execution
Constructor
◦ Memory De-Allocation and De-Binding
Contrasting with
Member Functions
• Object Lifetime
Parameterized
Default Parameters
◦ Starts with execution of Constructor Body
Overloaded ▷ Must follow Memory Allocation
Destructor ▷ As soon as Initialization ends and control enters Constructor Body
Contrasting with
Member Functions ◦ Ends with execution of Destructor Body
Default
Constructor ▷ As soon as control leaves Destructor Body
Object Lifetime ▷ Must precede Memory De-allocation
Automatic
Static
◦ For Objects of Built-in / Pre-Defined Types
Dynamic
▷ No Explicit Constructor / Destructor
Module Summary
▷ Lifetime spans from object definition to end of scope
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 20
Program 13.15: Complex: Object Lifetime: Automatic

Module 13 #include <iostream>


#include <cmath>
Intructors: Abir
Das and
using namespace std;
Sourangshu class Complex { private: double re_, im_; public:
Bhattacharya Complex(double re = 0.0, double im = 0.0): re_(re), im_(im) // Ctor
{ cout << "Ctor: (" << re_ << ", " << im_ << ")" << endl; }
Objectives & ~Complex() { cout << "Dtor: (" << re_ << ", " << im_ << ")" << endl; } // Dtor
Outline

Constructor double norm() { return sqrt(re_*re_ + im_*im_); }


Contrasting with void print() { cout << "|" << re_ << "+j" << im_ << "| = " << norm() << endl; }
Member Functions
};
Parameterized
Default Parameters
int main() {
Overloaded
Complex c(4.2, 5.3), d(2.4); // Complex::Complex() called -- c, then d -- objects ready
c.print(); // Using objects
Destructor
d.print();
Contrasting with
Member Functions
} // Scope over, objects no more available. Complex::~Complex() called -- d then c in the reverse order!
Default
Constructor -----
Object Lifetime Ctor: (4.2, 5.3)
Automatic
Ctor: (2.4, 0)
Static |4.2+j5.3| = 6.7624
Dynamic |2.4+j0| = 2.4
Module Summary
Dtor: (2.4, 0)
Dtor: (4.2, 5.3)
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 21
Program 13.16: Complex: Object Lifetime:
Automatic: Array of Objects
Module 13 #include <iostream>
#include <cmath>
Intructors: Abir using namespace std;
Das and
Sourangshu
class Complex { private: double re_, im_; public:
Bhattacharya Complex(double re = 0.0, double im = 0.0) : re_(re), im_(im) // Ctor
{ cout << "Ctor: (" << re_ << ", " << im_ << ")" << endl; }
Objectives & ~Complex() { cout << "Dtor: (" << re_ << ", " << im_ << ")" << endl; } // Dtor
Outline void opComplex(double i) { re_ += i; im_ += i; } // Some operation with Complex
Constructor double norm() { return sqrt(re_*re_ + im_*im_); }
Contrasting with void print() { cout << "|" << re_ << "+j" << im_ << "| = " << norm() << endl; }
Member Functions };
Parameterized
int main() { Complex c[3]; // Default ctor Complex::Complex() called thrice -- c[0], c[1], c[2]
Default Parameters
for (int i = 0; i < 3; ++i) { c[i].opComplex(i); c[i].print(); } // Use array
Overloaded
} // Scope over. Complex::~Complex() called thrice -- c[2], c[1], c[0] in the reverse order
Destructor
Contrasting with -----
Member Functions
Ctor: (0, 0)
Default Ctor: (0, 0)
Constructor
Ctor: (0, 0)
Object Lifetime |0+j0| = 0
Automatic |1+j1| = 1.41421
Static |2+j2| = 2.82843
Dynamic Dtor: (2, 2)
Module Summary Dtor: (1, 1)
Dtor: (0, 0)
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 22
Program 13.17: Complex: Object Lifetime: Static

Module 13
#include <iostream>
#include <cmath>
Intructors: Abir using namespace std;
Das and
Sourangshu
Bhattacharya class Complex { private: double re_, im_; public:
Complex(double re = 0.0, double im = 0.0): re_(re), im_(im) // Ctor
Objectives & { cout << "Ctor: (" << re_ << ", " << im_ << ")" << endl; }
Outline ~Complex() { cout << "Dtor: (" << re_ << ", " << im_ << ")" << endl; } // Dtor
Constructor
Contrasting with
double norm() { return sqrt(re_*re_ + im_*im_); }
Member Functions void print() { cout << "|" << re_ << "+j" << im_ << "| = " << norm() << endl; }
Parameterized };
Default Parameters Complex c(4.2, 5.3); // Static (global) object c
Overloaded
// Constructed before main starts. Destructed after main ends
Destructor int main() {
Contrasting with cout << "main() Starts" << endl; ----- OUTPUT -----
Member Functions
Complex d(2.4); // Ctor for d Ctor: (4.2, 5.3)
Default main() Starts
Constructor
c.print(); // Use static object Ctor: (2.4, 0)
Object Lifetime d.print(); // Use local object |4.2+j5.3| = 6.7624
Automatic } // Dtor for d |2.4+j0| = 2.4
Static Dtor: (2.4, 0)
Dynamic // Dtor for c Dtor: (4.2, 5.3)
Module Summary

CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 23


Program 13.18: Complex: Object Lifetime: Dynamic
#include <iostream>
Module 13
#include <cmath>
Intructors: Abir using namespace std;
Das and class Complex { private: double re_, im_; public:
Sourangshu
Bhattacharya Complex(double re = 0.0, double im = 0.0): re_(re), im_(im) // Ctor
{ cout << "Ctor: (" << re_ << ", " << im_ << ")" << endl; }
Objectives & ~Complex() { cout << "Dtor: (" << re_ << ", " << im_ << ")" << endl; } // Dtor
Outline double norm() { return sqrt(re_*re_ + im_*im_); }
Constructor
void print() { cout << "|" << re_ << "+j" << im_ << "| = " << norm() << endl; }
Contrasting with
};
Member Functions int main() { unsigned char buf[100]; // Buffer for placement of objects
Parameterized Complex* pc = new Complex(4.2, 5.3); // new: allocates memory, calls Ctor
Default Parameters Complex* pd = new Complex[2]; // new []: allocates memory ----- OUTPUT -----
Overloaded
// calls default Ctor twice Ctor: (4.2, 5.3)
Destructor Complex* pe = new (buf) Complex(2.6, 3.9); // placement new: only calls Ctor Ctor: (0, 0)
Contrasting with // No alloc. of memory, uses buf Ctor: (0, 0)
Member Functions
// Use objects Ctor: (2.6, 3.9)
Default pc->print(); |4.2+j5.3| = 6.7624
Constructor
pd[0].print(); pd[1].print(); |0+j0| = 0
Object Lifetime pe->print(); |0+j0| = 0
Automatic // Release of objects - can be done in any order |2.6+j3.9| = 4.68722
Static delete pc; // delete: calls Dtor, release memory Dtor: (4.2, 5.3)
Dynamic delete [] pd; // delete[]: calls 2 Dtor’s, release memory Dtor: (0, 0)
Module Summary pe->~Complex(); // No delete: explicit call to Dtor. Use with extreme care Dtor: (0, 0)
} Dtor: (2.6, 3.9)
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 24
Module Summary

Module 13

Intructors: Abir • Objects are initialized by Constructors that can be Parameterized and / or Overloaded
Das and
Sourangshu
Bhattacharya
• Default Constructor does not take any parameter – necessary for arrays of objects
Objectives &
• Objects are cleaned-up by Destructors. Destructor for a class is unique
Outline
• Compiler provides free Default Constructor and Destructor, if not provides by the
Constructor
Contrasting with
program
Member Functions
Parameterized • Objects have a well-defined lifetime spanning from execution of the beginning of the
Default Parameters
Overloaded
body of a constructor to the execution till the end of the body of the destructor
Destructor • Memory for an object must be available before its construction and can be released
Contrasting with
Member Functions only after its destruction
Default
Constructor

Object Lifetime
Automatic
Static
Dynamic

Module Summary

CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 25

You might also like