51
TCP1201 OOPDS 1 Class & Template Lecture 2

Lecture02 class -_templatev2

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Lecture02 class -_templatev2

TCP1201 OOPDS 1

Class & Template

Lecture 2

Page 2: Lecture02 class -_templatev2

TCP1201 OOPDS 2

Learning Objectives:• To understand object behaviors• To understand constructors• To understand destructors and deep copy• To understand update methods and query

methods• To understand const attributes, static attributes,

static methods, and const methods• To understand template

Page 3: Lecture02 class -_templatev2

TCP1201 OOPDS 3

Revisit Pointers• Why pointer is important?

1. Reference/Point to existing data without cloning the data.

2. Dynamic memory allocation (create the amount of data based on runtime need).

3. Dynamic polymorphism (Lecture 4)

• A pointer always stores the address of a data.• Before we can use a pointer, it must point to a

valid address that is achieved through:– Pointing it to an existing data, or– Using it to create a new data (use new operator).

Page 4: Lecture02 class -_templatev2

TCP1201 OOPDS

• Is pointer that does not point to an valid address.

• Use of dangling pointer generates runtime error easily.

4

Dangling Pointer

int* p; // 'p' usually does not point to // a valid address.*p = 10; // Runtime error usually.

p [ int* ]

?

Page 5: Lecture02 class -_templatev2

TCP1201 OOPDS 5

Point to Existing Data Without Cloning the Data

1432

3 a [ int ]

int a = 3;int *p = &a;cout << *p; // 3cout << p; // 1432

4324

1432 p [ int* ]

The ampersand '&' is called address operator which returns the address of variable 'a'.

'a' stores an int . 'p' stores the address of variable 'a'.

We say 'p' points to 'a'.

'p' is not a clone of 'a'.

Page 6: Lecture02 class -_templatev2

TCP1201 OOPDS

• To create new data dynamically.• We use new operator to create new data, and

later use delete operator to release the memory used by the data.

• The new operator allocates the memory needed for the new data, and returns the address of the new data.

6

Dynamic Memory Allocation (DMA)

int a = 3; // Automatic memory allocation.int* p; // 'p' does not point to a valid address.p = new int; // 'p' points to the new data....delete p; // Release the memory used by *p.

Page 7: Lecture02 class -_templatev2

TCP1201 OOPDS

• Use delete [] to release the memory used by a dynamic array.

7

Dynamic Memory Allocation (DMA)

int* p1 = new int; // Create 1 int.delete p1; // Release 1 int.

int* p2 = new int[4]; // Create a dynamic // array of 4 int.delete [] p2; // Release dynamic array.

1432

1432

p1 [ int* ]

?

?

?

?

?

1100

p2 [int* ][int]

[int]

[int]

[int]

1100

1104

1108

1112

[int]

Page 8: Lecture02 class -_templatev2

TCP1201 OOPDS 8

4 Types of Object Behaviors1. Constructors – Specify how a new object is

created.

2. Queries – Return or find out, but not modify, the value of attributes of an object, e.g. get methods.

3. Updates – Modify the value of attributes of an object, e.g. set methods.

4. Destructors – Specify how an object is destroyed.

Page 9: Lecture02 class -_templatev2

TCP1201 OOPDS 9

Constructors• Constructors are special types of methods that are

used to initialize object attributes.• They are invoked/called automatically whenever an

instance/object of a class is created.

class Student { ...};

int main() { Student s1; // Create an instance, call a constructor. Student *ps = new Student; // Create an instance, call a constructor. ... delete ps; // Release the memory used by *ps.}

Page 10: Lecture02 class -_templatev2

TCP1201 OOPDS 10

Constructors• Always have the same name as the class name.• Have no return value.• 3 types of constructors: default, overloaded, copy.• A class can have more than one constructor.

class Student { int id; string name; public: Student(); // Default constructor Student(int id); // Overloaded constructor Student(string name); // Overloaded constructor Student(int id, string name); // Overloaded constructor Student(const Student& existingStudent); // Copy constructor ...}; Constructor name is the same as the class

name

Page 11: Lecture02 class -_templatev2

TCP1201 OOPDS

Default Constructors• Enable us to initialize attributes to preferred default values

when no argument is not provided during object creation.• A class can have only one default constructor.

class Student { int id; string name; public: Student() { // Default constructor has no parameter. name = "Unknown"; // Set default name value to "Unknown". id = 0; // Set default id value to 0. }};int main() { Student s1; // Call default constructor, id=0, name="Unknown". Student *ps = new Student; // Call default constructor, id=0, name="Unknown". ... delete ps; ...

Page 12: Lecture02 class -_templatev2

TCP1201 OOPDS

Without Default Constructors• If you do not provide both default constructor and

overloaded constructor, C++ automatically creates a default constructor with blank implementation.// Your codeclass Student { // No default constructor or // overloaded constructor is provided. int id; string name;};

// Compiler codeclass Student { int id; string name; public: Student() // Compiler's default constructor. { } // Blank implementation. name = "", id = ?};int main() { Student s1; // Call default constrcutor. name = "", id = ? Student *ps = new Student; // name = "", id = ? ...

Page 13: Lecture02 class -_templatev2

TCP1201 OOPDS

• Enable us to initialize attributes before constructor body is executed.

• Is placed between the constructor parameter list and constructor body.

• General format:

ClasName (<parameter list>) : <initializer list> { ... }

13

Constructor Initializer List

Constructor name

Colon

Initializer list

Constructor body

ClassName (datatype1 param1, datatype2 param2) : attribute1 (param1), attribute2 (param2) { ... }

Page 14: Lecture02 class -_templatev2

TCP1201 OOPDS

Constructor Initializer List • The previous Student's default constructor can

be rewritten to use constructor initializer list as follow:

// Use constructor initializer list.class Student { int id; string name; public: Student () // Default constructor : name("Unknown"), id(0) // Initialize name = "Unknown", id = 0. { }};int main() { Student s1; // name = "Unknown", id = 0. Student *ps = new Student; // name = "Unknown", id = 0. ...

Page 15: Lecture02 class -_templatev2

TCP1201 OOPDS

Constructor Initializer List • Is the only way to initialize const attributes

(discuss later), and is also only way to call superclass' constructor (Lecture 3).

• Hence is the preferred way to initialize attributes.

• Does not work on static attributes (discuss later).

Page 16: Lecture02 class -_templatev2

TCP1201 OOPDS 16

Example: Default Constructorclass Student { int id; string name; public: Student() // Default constructor : id(0), name("Unknown") { cout << "A Student object is created!\n"; } void setName (string name) { this->name = name; } void setID (int id) { this->id = id; } string getName() { return name; } int getID() { return id; } };int main() { Student* s1 = new Student; // Call default constructor, // id = 0, name = "Unknown" cout << "Student id = " << s1->getID() << endl << "Student name = " << s1->getName() << endl; s1->setID (123); // id = 123 s1->setName ("Ali"); // name = "Ali" cout << "Student id = " << s1->getID() << endl << "Student name = " << s1->getName() << endl; delete s1;}

Output:

A Student object is created!Student id = 0Student name = "Unknown"Student id = 123Student name = "Ali"

Page 17: Lecture02 class -_templatev2

TCP1201 OOPDS

Overloaded Constructors• Constructors that have parameter(s).• Initialize attributes to values passed as arguments.

class Student { int id; string name; public: Student (int id, string name) // Overloaded constructor. : id(id), name(name) // attribute1(param1), attribute2(param2). { }};int main() { Student s1 (123, "Ali"); // Call overloaded constructor, id = 123, // name = "Ali" Student *ps; ps = new Student (234, "Bob"); // Call overloaded constructor, id = 234, // name = "Bob" ...

Page 18: Lecture02 class -_templatev2

TCP1201 OOPDS

Overloaded Constructors• A class can have more than one overloaded constructors

as long as the parameter lists follow the rules of function overloading, that is no 2 overloaded constructors should have the same number of parameters and the same type of parameters.

class Student { int id; string name; public: Student () {...} // Default constructor Student (int id) {...} // Overloaded constructor 1 Student (string name) {...} // Overloaded constructor 2 Student (int id, string name) {...} // Overloaded constructor 3 Student (const Student& s) {...} // Copy constructor};int main() { Student s1; // Call default constructor Student s2 ("Ann"); // Call overloaded constructor 2 Student s3 (234, "Bob"); // Call overloaded constructor 3 Student s4 (123); // Call overloaded constructor 1 Student s5 (s4); // Call copy constructor...

Page 19: Lecture02 class -_templatev2

TCP1201 OOPDS

Overloaded Constructors• We may provide default argument to constructor

parameters.• If all parameters of an overloaded constructor have default

argument, the overloaded constructor serves as a default constructor too.

class Student { string name; int id; public: Student (int id=0, string name="Unknown") // 2-in-1: default constructor + // overloaded constructor. : id(id), name(name) {}};int main() { Student *p1 = new Student; // Call default constructor, // id = 0, name = "Unknown". Student *p2 = new Student (234, "Bob"); // Call overloaded constructor, // id = 234, name = "Bob". ...

Page 20: Lecture02 class -_templatev2

TCP1201 OOPDS 20

Copy Constructors• Initializes a new object by copying the value of attributes

from an existing object of the same class.• Is invoked when an instance is created with one of the

following ways:

Student x(123, "Michael"); // x invokes overloaded constructor.Student y = x; // y invokes copy constructor, copy from x.Student z(y); // z invokes copy constructor, copy from y.Student* s = new Student(y); // *s invokes copy constructor, // copy from y.// All 4 objects x, y, z and *s have id=123 and name="Michael".

Page 21: Lecture02 class -_templatev2

TCP1201 OOPDS 21

Copy Constructors• A class can have one copy constructor only.• Copy constructor must have the following

header/interface/signature:

const prevents existing instance from being modified by the copy constructor

Parameter name refers to the source instance that is being “copied”

Pass by reference to avoid cloning the parameter

ClassName (const ClassName& existingInstance);

Parameter is of the same type as the class

Student (const Student& existingStudent);

Page 22: Lecture02 class -_templatev2

TCP1201 OOPDS 22

Copy Constructors• If we do not provide a copy constructor, C++

automatically provides a default copy constructor that copies the value of all attributes from current instance to the new instance. This type of copying is called shallow copy.

• For our Student class, C++ automatically provides the following default copy constructor.

class Student { int id; // 2 attributes, no dynamic memory allocation. string name; ... // C++ provides the following default copy constructor. Student (const Student& s) : id(s.id), name(s.name) // shallow copy 2 attributes. { }};

Page 23: Lecture02 class -_templatev2

TCP1201 OOPDS 23

Deep Copy• We usually do not have to provide a copy constructor,

unless we want to perform additional initialization that is not provided by the default copy constructor. For example, deep copy a pointer attribute that is created using dynamic memory allocation (DMA).

• If a pointer attribute of a source object uses DMA to create its data, shallow copy won't create that data in the target object but just makes the source object shares the data with target object.

Page 24: Lecture02 class -_templatev2

TCP1201 OOPDS 24

Deep Copy Example• Consider a scenario whereby a student have many

marks.• We declare a pointer named marks in Student class, and

use it to create a dynamic array to store the marks.• Each student should have their own dynamic array to

store their marks, and they should not share the same dynamic array.

• Shallow copying the marks attribute would result in both the source student and target student sharing the same dynamic array. Which is considered wrong.

• Deep copying the marks attribute would ensure that each student would have their own dynamic array for storing the marks.

Page 25: Lecture02 class -_templatev2

TCP1201 OOPDS 25

Problem: Shallow copy a pointer attribute in Copy Constructor

class Student { int size; double *marks; // Pointer attribute. public: Student (int size); // Overloaded constructor. // No copy constructor is written, C++ provides one. void setMark (int index, int mark); void print();};Student::Student (int size) : size(size) { this->marks = new double[size]; // Create dynamic array. for (int i = 0; i < size; i++) marks[i] = 0;}void Student::setMark (int index, int mark) { marks[index] = mark;}void Student::print() { cout << "Marks = "; for (int i = 0; i < size; i++) cout << marks[i] << " "; cout << endl;}

int main() { Student *s1, *s2; s1 = new Student (3); s2 = new Student (*s1); s1->print(); // 0 0 0 s2->print(); // 0 0 0 s1->setMark (0, 70); s1->setMark (1, 80); s1->setMark (2, 90); s1->print(); // 70 80 90 s2->print(); // 70 80 90 delete s1; delete s2;}

Output:Marks = 0 0 0Marks = 0 0 0Marks = 70 80 90Marks = 70 80 90

s2 points to s1's marks array, hence sharing one marks array

Page 26: Lecture02 class -_templatev2

TCP1201 OOPDS 26

Solution: Deep copy in Copy Constructorclass Student { int size; double *marks; // Pointer attribute. public: Student (int size); // Overloaded constructor. Student (const Student& s); // Copy constructor. void setMark (int index, int mark); void print();};Student::Student (int size) : size(size) { this->marks = new double[size]; // Create dynamic array. for (int i = 0; i < size; i++) marks[i] = 0;}Student::Student (const Student& s) // Copy constructor. : size(s.size) { this->marks = new double[size]; // Create dynamic array. for (int i = 0; i < size; i++) marks[i] = s.marks[i]; // Copy array.}void Student::setMark (int index, int mark) { marks[index] = mark;}void Student::print() { cout << "Marks = "; for (int i = 0; i < size; i++) cout << marks[i] << " "; cout << endl;}

int main() { Student *s1, *s2; s1 = new Student (3); s2 = new Student (*s1); s1->print(); // 0 0 0 s2->print(); // 0 0 0 s1->setMark (0, 70); s1->setMark (1, 80); s1->setMark (2, 90); s1->print(); // 70 80 90 s2->print(); // 0 0 9\0 delete s1; delete s2;}

Output:Marks = 0 0 0Marks = 0 0 0Marks = 70 80 90Marks = 0 0 0

s1 and s2 each have a different marks array

Page 27: Lecture02 class -_templatev2

TCP1201 OOPDS 27

Destructors• A destructor is a special type of method that is

invoked whenever an instance is destroyed (de-allocating an instance).

• Destructors are automatically called when an automatically allocated instance goes out of scope, or when a dynamically allocated instance is explicitly deleted (using delete operator).

• Destructors have no return value and no parameter

• There is only one destructor for each class.• Destructor has the same name as the class,

except that it is preceded by a tilde ‘~’.

class Student { ... ~Student();};

Page 28: Lecture02 class -_templatev2

TCP1201 OOPDS 28

Destructors• Destructors are generally used to perform any

cleanup necessary prior to an instance being destroyed. For example deleting dynamically allocated objects:

// Continue from Deep Copy exampleclass Student { double *marks; // Pointer attribute. public: ... ~Student();};Student::~Student() { delete [] marks; // Destroy dynamic attribute.}

Page 29: Lecture02 class -_templatev2

TCP1201 OOPDS 29

Destructors• Same as the default constructor and copy

constructor , if you do not provide a destructor, C++ provides a default destructor with blank implementation.

// Compiler codeclass Student { public: -Student() { // Compiler's default destructor, // blank implementation. }};

// Your codeclass Student { // No destructor is provided.};

Page 30: Lecture02 class -_templatev2

TCP1201 OOPDS 30

Example: Destructorclass Student { int id; public: Student(int id); // constructor ~Student(); // destructor};Student::Student(int id) : id(id) { cout << "Object " << id << " created.\n";}Student::~Student() { cout << "Object " << id << " destroyed.\n";}int main() { Student* s0 = new Student(000); // constructor for 000 delete s0; // destructor for 000 Student s1(111); // constructor for 111 Student s2(222); // constructor for 222 Student* s3 = new Student(333); // constructor for 333} // End of main() auto-calls destructor for 222 and 111.// Why destructor for 333 not called? No "delete s3;"

Output:

Object 000 created.Object 000 destroyed.Object 111 created.Object 222 created.Object 333 created.Object 222 destroyed.Object 111 destroyed.

Page 31: Lecture02 class -_templatev2

TCP1201 OOPDS 31

Query Methods• Query methods (also called accessors) are methods

that are used to inquire (find out) about the value of an instance’s attributes.

• Query method does not modify the value of any of the object’s attributes.

class Student { int id; string name; ... int getId() { // Returns the value of attribute id. return id; } string getName() { // Returns the value of attribute name. return name; }};

Page 32: Lecture02 class -_templatev2

TCP1201 OOPDS 32

Update Methods• Update methods (also called mutators) are methods

that modify the value of attribute(s) in an object.

class Student { int id; string name; ... void setId (int id) { // Modify attribute 'id'. this->id = id; } void setName (string name) { // Modify attribute 'name'. this->name = name; }};

Page 33: Lecture02 class -_templatev2

TCP1201 OOPDS 33

Update Methods• Recall that one of the reasons to have encapsulation is to

ensure data integrity.• Update methods allow us to achieve data integrity.• In the following example, the setGPA update method

ensures that the new GPA value is within 0-4.

int Student::setGPA (double newGPA) { if ((newGPA >= 0.0) && (newGPA <= 4.0)) { gpa = newGPA; return 0; // Return 0 to indicate success } else { return -1; // Return -1 to indicate failure }}

Page 34: Lecture02 class -_templatev2

TCP1201 OOPDS 34

Update & Query Behaviors• Identify the type of behaviors of

the Student class on the right.• Query behaviors:

– getId, show_subjects.

• Update behaviors:– register_subject (modify attribute

subjects).– withdraw_subject (modify attribute

subjects).

-id: int-subjects:string[*]

+getId():int+setId(id:int):void+show_subjects():void+register_subject():void+withdraw_subject():void

Student

Page 35: Lecture02 class -_templatev2

TCP1201 OOPDS 35

const Attributes• const attributes are attributes that its value cannot

be changed throughout the lifetime of the instance.• It must be initialized using constructor initializer list.

class Student { const int id; // Use keyword "const" to declare const string name; // const attribute. public: Student (int id, string name) // Overloaded constructor. : id(id), name(name) // Constructor initializer list. {}};int main() { Student* s1 = new Student(123, "Michael"); // Cannot change s1's id and name after creation. ...}

Page 36: Lecture02 class -_templatev2

TCP1201 OOPDS 36

static Attributes• Are attributes that are shared across all instances of a

class.• The program creates only a single instance of a static

attribute, regardless of how many instances of the class are created.

• Cannot be initialized within the class or using constructor initializer list.

• Must be initialized outside the class declaration using scope resolution operator "::".

class Student { string name; static int count; // Use keyword "static" to declare // static attribute.}; // end of classint Student::count = 0; // Initialize count to 0.

Page 37: Lecture02 class -_templatev2

TCP1201 OOPDS 37

static Methods• A static method can be invoked without creating an

instance of the class.• Use the scope resolution operator "::".

• They cannot access non-static attributes or non-static methods.

• The primary reason to declare static methods is to be able to access static attributes without creating an instance of the class.

Page 38: Lecture02 class -_templatev2

TCP1201 OOPDS 38

Example: static Membersclass Student { string name; static int count; public: Student() { ++count; } ~Student() { --count; } static int getCount() { return count; }};int Student::count = 0;

int main() { cout << "Student count = " << Student::getCount() << endl; Student a; // create 1 instance cout << "Student count = " << a.getCount() << endl; Student* b = new Student; // create 1 instance. cout << "Student count = " << b->getCount() << endl; { Student c; // create 1 instance. cout << "Student count = " << c.getCount() << endl; } // c is destroyed delete b; // b is destroyed. cout << "Student count = " << Student::getCount() << endl; // Why not zero?}

Output:

Student count = 0Student count = 1Student count = 2Student count = 3Student count = 1

Page 39: Lecture02 class -_templatev2

TCP1201 OOPDS 39

static Members

int main() { cout << Student::getCount(); // Invokes static method // without instance.

Student* s1 = new Student; // 1 instance. cout << s1->getCount(); // Invokes static method // via the instance s1. vector<Student> s; // 100 instances. cout << s[0].getCount(); // Invokes static method // via the instance s[0]. // At this point, there are 101 instances of name, // but only 1 instance of count. delete s1;}

Page 40: Lecture02 class -_templatev2

TCP1201 OOPDS 40

const and static Attributes

• To summarize:– Attributes that you want to “share” across all

instances of a class should be declared as static.

– Attributes that you want to prevent modification after the creation of the instance should be declared as const.

Page 41: Lecture02 class -_templatev2

TCP1201 OOPDS 41

const Methods• Query methods are typically declared as const to indicate

that the methods should not modify the value of any attributes.

• A compile-error will be generated if a const method tries to:– Modify the value of an attribute.– Call to non-const or non-static method.

class Student { int gpa; public: void calc() { ... } // Non-const method. void try() const { // const method. gpa = 4.0; // Compile-error, try to modify attribute. calc(); // Compile-error, call non-const/non-static method. } int getGPA() const { // const method, fine, no code modifies attribute. return gpa; }};

Page 42: Lecture02 class -_templatev2

TCP1201 OOPDS 42

Template

• Template allows us to write generic functions or classes (called function template, class template) that accept any data type as parameters or attributes.

• During compilation, the compiler will produce a separate definition for every data type that uses the template.

Page 43: Lecture02 class -_templatev2

TCP1201 OOPDS 43

Function Template • To swap 2 integers, we may write the following

function:

• To swap 2 strings, we need to write another function:

The only different between these 2 functions are data type. Template is the best solution.

void Swap (int& m, int& n) { int temp = m; m = n; n = temp;}

void Swap (string& s1, string& s2) { string temp = s1; s1 = s2; s2 = temp;}

Page 44: Lecture02 class -_templatev2

TCP1201 OOPDS 44

Function Template Example• Template version of Swap function:

template <typename T>void Swap(T& x, T& y) { T temp = x; x = y; y = temp;}int main() { int m = 22, n = 66; Swap(m, n); // integers cout << "m = " << m << endl << "n = " << n << endl; string s1 = "Michael", s2 = "Kelly"; Swap(s1, s2); // strings cout << "s1 = " << s1 << endl << "s2 = " << s2 << endl;}

Output:m = 66n = 22s1 = Kellys2 = Michael

Compiler produces 2 definitions of Swap() functions: one for int, one for string.

Page 45: Lecture02 class -_templatev2

TCP1201 OOPDS 45

Declaring Function Template • Function templates are declared in a similar as

ordinary functions, except that it is preceded by the specification below:

• Type parameter 'T' is used in place of ordinary data types within the function definition.

• A template may have several type parameters:

template <typename T> // Less confusing, ortemplate <class T> // more confusing, class?

template <typename T, typename U, typename V>

Page 46: Lecture02 class -_templatev2

TCP1201 OOPDS 46

Declaring Class Template • Class templates are declared in a similar way

as ordinary classes, except that it is preceded by the specification below:

• A class template may have several type parameters:

template <typename T>class Box { T data; ...

template <typename T, typename U> class Box { T data1; U data2;...};

Page 47: Lecture02 class -_templatev2

TCP1201 OOPDS 47

Class Template Example 1

template <typename T>class Pair { T a; T b; public: void set (T a, T b) { this->a = a; this->b = b; } T getA() { return a; } T getB() { return b; }};

Output:3 5Peter JacksonP J

Define a class template Pair that have 2 attributes of the same type.

int main() { Pair<int> p1; p1.set (3,5); Pair<string> p2; p2.set ("Peter", "Jackson"); Pair<char> *p3 = new Pair<char>; p3->set ('P','J'); cout << p1.getA() << " " << p1.getB() << endl << p2.getA() << " " << p2.getB() << endl << p3->getA() << " " << p3->getB(); delete p3;}

Page 48: Lecture02 class -_templatev2

TCP1201 OOPDS 48

Class Template Example 1

template <typename T>class Pair { T a; T b; public: void set (T a, T b) { this->a = a; this->b = b; } T getA() { return a; } T getB() { return b; }};

Output:3 5Peter JacksonP J

Class template allows us to write one class that works with different data types.

int main() { Pair<int> p1; p1.set (3,5); Pair<string> p2; p2.set ("Peter", "Jackson"); Pair<char> *p3 = new Pair<char>; p3->set ('P','J'); cout << p1.getA() << " " << p1.getB() << endl << p2.getA() << " " << p2.getB() << endl << p3->getA() << " " << p3->getB(); delete p3;}

Page 49: Lecture02 class -_templatev2

TCP1201 OOPDS 49

Class Template Example 2: Multiple Type Parameters

template <typename T, typename U>class Pair { T a; U b; public: void set (T a, U b) { this->a = a; this->b = b; } T getA() { return a; } U getB() { return b; }};

Output:1 AB Boy99 99

Attributes may have different data types.

int main() { Pair<int,char> p1; p1.set (1, 'A'); Pair<char,string> p2; p2.set ('B',"Boy"); Pair<int,int> *p3 = new Pair<int,int>; p3->set (99,99); cout << p1.getA() << " " << p1.getB() << endl << p2.getA() << " " << p2.getB() << endl << p3->getA() << " " << p3->getB(); delete p3;}

Page 50: Lecture02 class -_templatev2

TCP1201 OOPDS 50

Revisit STL vector Class• The vector class provided by C++ Standard

Template Library (STL) is actually a class template.

• vector is better than array when we need to insert and/or remove data from a collection of data, because vector can grow and shrink automatically.

Page 51: Lecture02 class -_templatev2

TCP1201 OOPDS 51

vector Example...#include <vector>using namespace std;class Student { ... };int main() { vector<Student> s; // vector of Student. // Insert at back. s.push_back (Student(22,"Bob")); // Bob // Insert at beginning or index 0. s.insert (s.begin(), Student(11,"Ali")); // Ali Bob // Insert at index 1. s.insert (s.begin()+1, Student(33,"Cat")); for (int i = 0; i < s.size(); i++) // Ali Cat Bob cout << s[i].getName() << " "; cout << endl; // Erase item at index 1. s.erase (s.begin()+1); // Ali Bob // Erase item at index 0. s.erase (s.end()); // Ali for (int i = 0; i < s.size(); i++) cout << s[i] .getName()<< endl;}