SlideShare ist ein Scribd-Unternehmen logo
1 von 51
Class & Template




       Lecture 2


TCP1201 OOPDS
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



              TCP1201 OOPDS
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).
             TCP1201 OOPDS
Dangling Pointer
• Is pointer that does not point to an valid
  address.
• Use of dangling pointer generates runtime
  error easily.
  int* p; // 'p' usually does not point to
          // a valid address.
  *p = 10; // Runtime error usually.



                             ?
            p [ int* ]

            TCP1201 OOPDS
Point to Existing Data Without
         Cloning the Data
                                       1432
                                          3     a [ int ]
    int a = 3;
    int *p = &a;                        4324
                                        1432     p [ int* ]
    cout << *p; // 3
    cout << p; // 1432
                           'a' stores an int . 'p' stores
The ampersand '&' is       the address of variable 'a'.
called address operator
which returns the          We say 'p' points to 'a'.
address of variable 'a'.   'p' is not a clone of 'a'.


                 TCP1201 OOPDS
Dynamic Memory Allocation
            (DMA)
 • 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.
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.
              TCP1201 OOPDS
Dynamic Memory Allocation
           (DMA)                                              1432
                                                               ?
• Use delete [] to release the                1432

                                             p1 [ int* ]      [int]
  memory used by a dynamic array.

                                       1100           1100
                                                              ?       [int]
                                      p2 [int* ]
                                                       1104
                                                              ?       [int]
int* p1 = new int; // Create 1 int.                   1108
delete p1; // Release 1 int.                                  ?       [int]
                                                      1112
                                                              ?       [int]
int* p2 = new int[4]; // Create a dynamic
                      // array of 4 int.
delete [] p2; // Release dynamic array.


             TCP1201 OOPDS
4 Types of Object Behaviors
1. 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.


             TCP1201 OOPDS
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.
}




                   TCP1201 OOPDS
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

                   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;
  ...


                      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 code
   class Student {   // No default constructor or
                     // overloaded constructor is provided.
     int id;
     string name;
   };

   // Compiler code
   class 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 = ?
     ...

                     TCP1201 OOPDS
Constructor Initializer List
• 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> { ... }


Constructor name                Colon                      Constructor body
                                        Initializer list

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



                   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.
  ...




                 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).




               TCP1201 OOPDS
Example: Default Constructor
class Student {                                     Output:
  int id;
  string name;                                      A Student object is created!
 public:                                            Student id   = 0
  Student()       // Default constructor            Student name = "Unknown"
    : id(0), name("Unknown") {                      Student id   = 123
    cout << "A Student object is created!n";       Student name = "Ali"
  }
  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;
}


                       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"
  ...




                      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
...                   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".
  ...

                      TCP1201 OOPDS
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".




                 TCP1201 OOPDS
Copy Constructors
• A class can have one copy constructor only.
• Copy constructor must have the following
  header/interface/signature:
         Parameter name refers to the source instance that is being “copied”

Parameter is of the same type as the class

         ClassName (const ClassName& existingInstance);

                              Pass by reference to avoid cloning the parameter

const prevents existing instance from being modified by the copy constructor

            Student (const Student& existingStudent);

                     TCP1201 OOPDS
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.
   { }
 };
                 TCP1201 OOPDS
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.




                  TCP1201 OOPDS
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.
                  TCP1201 OOPDS
Problem: Shallow copy a pointer attribute in
                    Copy Constructor
class Student {                                             int main() {
   int size;                                                  Student *s1, *s2;
   double *marks; // Pointer attribute.                       s1 = new Student (3);
 public:                                                      s2 = new Student (*s1);
   Student (int size); // Overloaded constructor.             s1->print(); // 0 0 0
   // No copy constructor is written, C++ provides one.       s2->print(); // 0 0 0
   void setMark (int index, int mark);                        s1->setMark (0, 70);
   void print();                                              s1->setMark (1, 80);
};                                                            s1->setMark (2, 90);
Student::Student (int size)                                   s1->print(); // 70 80 90
 : size(size) {                                               s2->print(); // 70 80 90
 this->marks = new double[size]; // Create dynamic array.     delete s1;
 for (int i = 0; i < size; i++)                               delete s2;
   marks[i] = 0;                                            }
}
void Student::setMark (int index, int mark) {
 marks[index] = mark;                                         Output:
}                                                             Marks =    0 0 0
void Student::print() {                                       Marks =    0 0 0
 cout << "Marks = ";
 for (int i = 0; i < size; i++)                               Marks =    70 80 90
   cout << marks[i] << " ";                                   Marks =    70 80 90
 cout << endl;
}

                                                   s2 points to s1's marks
                                                   array, hence sharing one marks
                                                   array
                           TCP1201 OOPDS
Solution: Deep copy in Copy Constructor
class Student {                                              int main() {
  int size;                                                     Student *s1, *s2;
  double *marks; // Pointer attribute.                          s1 = new Student (3);
 public:                                                        s2 = new Student (*s1);
  Student (int size);         // Overloaded constructor.        s1->print(); // 0 0 0
  Student (const Student& s); // Copy constructor.              s2->print(); // 0 0 0
  void setMark (int index, int mark);                           s1->setMark (0, 70);
  void print();                                                 s1->setMark (1, 80);
};                                                              s1->setMark (2, 90);
Student::Student (int size)                                     s1->print(); // 70 80 90
 : size(size) {                                                 s2->print(); // 0 0 90
 this->marks = new double[size]; // Create dynamic array.       delete s1;
 for (int i = 0; i < size; i++)                                 delete s2;
  marks[i] = 0;                                              }
}
Student::Student (const Student& s) // Copy constructor.
 : size(s.size) {                                              Output:
 this->marks = new double[size]; // Create dynamic array.      Marks = 0 0 0
 for (int i = 0; i < size; i++)                                Marks = 0 0 0
  marks[i] = s.marks[i]; // Copy array.
}                                                              Marks = 70 80 90
void Student::setMark (int index, int mark) {                  Marks = 0 0 0
 marks[index] = mark;
}
void Student::print() {
 cout << "Marks = ";                                  s1 and s2 each have a
 for (int i = 0; i < size; i++)
  cout << marks[i] << " ";                            different marks array
 cout << endl;
}
                           TCP1201 OOPDS
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();
                                    };

                TCP1201 OOPDS
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 example
        class Student {
          double *marks; // Pointer attribute.
         public:
          ...
          ~Student();
        };
        Student::~Student() {
          delete [] marks; // Destroy dynamic attribute.
        }



              TCP1201 OOPDS
Destructors
• Same as the default constructor and copy constructor
  , if you do not provide a destructor, C++ provides a
  default destructor with blank implementation.
   // Your code
   class Student { // No destructor is provided.
   };



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



              TCP1201 OOPDS
Example: Destructor
class Student {
 int id;                                              Output:
 public:
  Student(int id); // constructor                     Object 000   created.
  ~Student();      // destructor                      Object 000   destroyed.
};                                                    Object 111   created.
Student::Student(int id)                              Object 222   created.
  : id(id) {                                          Object 333   created.
  cout << "Object " << id << " created.n";           Object 222   destroyed.
}                                                     Object 111   destroyed.
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;"




                      TCP1201 OOPDS
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;
  }
};


               TCP1201 OOPDS
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;
  }
};




              TCP1201 OOPDS
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
        }
       }




                   TCP1201 OOPDS
Update & Query Behaviors
• Identify the type of behaviors of
  the Student class on the right.
• Query behaviors:
                                                    Student
   – getId, show_subjects.
                                          -id: int
• Update behaviors:                       -subjects:string[*]
                                          +getId():int
   – register_subject (modify attribute   +setId(id:int):void
     subjects).                           +show_subjects():void
   – withdraw_subject (modify attribute   +register_subject():void
                                          +withdraw_subject():void
     subjects).



                  TCP1201 OOPDS
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.
   ...
 }

                   TCP1201 OOPDS
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 class
  int Student::count = 0; // Initialize count to 0.


               TCP1201 OOPDS
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.




               TCP1201 OOPDS
Example: static Members
class Student {                int main() {
  string name;                   cout << "Student count = "
  static int count;                   << Student::getCount() << endl;
 public:                         Student a; // create 1 instance
  Student() { ++count; }         cout << "Student count = "
  ~Student() { --count; }             << a.getCount() << endl;
  static int getCount() {        Student* b = new Student; // create 1 instance.
    return count;                cout << "Student count = "
  }                                   << b->getCount() << endl;
};                               {
int Student::count = 0;            Student c; // create 1 instance.
                                   cout << "Student count = "
                                        << c.getCount() << endl;
                                 } // c is destroyed
                                 delete b; // b is destroyed.
                                 cout << "Student count = "
Output:
                                      << Student::getCount() << endl;
                                 // Why not zero?
Student   count   =   0        }
Student   count   =   1
Student   count   =   2
Student   count   =   3
Student   count   =   1


                          TCP1201 OOPDS
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;
}


                  TCP1201 OOPDS
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.




              TCP1201 OOPDS
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;
 }
};




                     TCP1201 OOPDS
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.




             TCP1201 OOPDS
Function Template
• To swap 2 integers, we may write the following
  function:     void Swap (int& m, int& n) {
                      int temp = m;
                      m = n;
                      n = temp;
                  }

• To swap 2 strings, we need to write another
  function:      void Swap (string& s1, string& s2)   {
                      string temp = s1;
                      s1 = s2;
                      s2 = temp;
                  }

The only different between these 2 functions are
data type. Template is the best solution.
              TCP1201 OOPDS
Function Template Example
 • Template version of Swap function:
template <typename T>                    Compiler produces 2
void Swap(T& x, T& y) {                  definitions of
  T temp = x;
                                         Swap() functions:
  x = y;
  y = temp;
                                         one for int, one for
}                                        string.
int main() {
                                         Output:
  int m = 22, n = 66;
  Swap(m, n);   // integers              m = 66
  cout << "m = " << m << endl            n = 22
       << "n = " << n << endl;           s1 = Kelly
  string s1 = "Michael", s2 = "Kelly";   s2 = Michael
  Swap(s1, s2); // strings
  cout << "s1 = " << s1 << endl
       << "s2 = " << s2 << endl;
}

                TCP1201 OOPDS
Declaring Function Template
• Function templates are declared in a similar as
  ordinary functions, except that it is preceded
  by the specification below:
template <typename T> // Less confusing, or
template <class T>    // more confusing, class?

• 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, typename U, typename V>



             TCP1201 OOPDS
Declaring Class Template
• Class templates are declared in a similar way
  as ordinary classes, except that it is preceded
  by the specification below: template <typename    T>
                               class Box {
                                 T data;
                                 ...

• A class template may have several type
  parameters: template <typename T, typename    U>
                 class Box {
                   T data1;
                   U data2;
                 ...
                 };

             TCP1201 OOPDS
Class Template Example 1
Define a class template       int main() {
                                Pair<int> p1;
Pair that have 2 attributes     p1.set (3,5);
of the same type.               Pair<string> p2;
                                p2.set ("Peter", "Jackson");
template <typename T>           Pair<char> *p3 = new
                                                 Pair<char>;
class Pair {                    p3->set ('P','J');
  T a;                          cout << p1.getA() << " "
  T b;                               << p1.getB() << endl
 public:                             << p2.getA() << " "
                                     << p2.getB() << endl
  void set (T a, T b) {              << p3->getA() << " "
    this->a = a;                     << p3->getB();
    this->b = b;                delete p3;
  }                           }
  T getA() { return a; }  Output:
  T getB() { return b; }  3 5
};                        Peter Jackson
              TCP1201 OOPDS J
                          P
Class Template Example 1
Class template allows us to   int main() {
                                Pair<int> p1;
write one class that works      p1.set (3,5);
with different data types.      Pair<string> p2;
                                p2.set ("Peter", "Jackson");
 template <typename T>          Pair<char> *p3 = new
                                                 Pair<char>;
 class Pair {                   p3->set ('P','J');
   T a;                         cout << p1.getA() << " "
   T b;                              << p1.getB() << endl
  public:                            << p2.getA() << " "
                                     << p2.getB() << endl
   void set (T a, T b) {             << p3->getA() << " "
     this->a = a;                    << p3->getB();
     this->b = b;               delete p3;
   }                          }
   T getA() { return a; }  Output:
   T getB() { return b; }  3 5
 };                        Peter Jackson
               TCP1201 OOPDS J
                           P
Class Template Example 2:
       Multiple Type Parameters
Attributes may have           int main() {
                                Pair<int,char> p1;
different data types.           p1.set (1, 'A');
                                Pair<char,string> p2;
template <typename T,
                                p2.set ('B',"Boy");
          typename U>           Pair<int,int> *p3 = new
class Pair {                                  Pair<int,int>;
  T a;                          p3->set (99,99);
                                cout << p1.getA() << " "
  U b;
                                     << p1.getB() << endl
 public:                             << p2.getA() << " "
  void set (T a, U b) {              << p2.getB() << endl
    this->a = a;                     << p3->getA() << " "
                                     << p3->getB();
    this->b = b;
                                delete p3;
  }                           }
  T getA() { return a; }
  U getB() { return b; }     Output:
                             1 A
};                           B Boy
                TCP1201   OOPDS 99
                             99
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.




             TCP1201 OOPDS
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;
}
              TCP1201 OOPDS

Weitere ähnliche Inhalte

Was ist angesagt?

data Structure Lecture 1
data Structure Lecture 1data Structure Lecture 1
data Structure Lecture 1Teksify
 
Lecture06 methods for-making_data_structures_v2
Lecture06 methods for-making_data_structures_v2Lecture06 methods for-making_data_structures_v2
Lecture06 methods for-making_data_structures_v2Hariz Mustafa
 
Java Generics for Dummies
Java Generics for DummiesJava Generics for Dummies
Java Generics for Dummiesknutmork
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondMario Fusco
 
On Parameterised Types and Java Generics
On Parameterised Types and Java GenericsOn Parameterised Types and Java Generics
On Parameterised Types and Java GenericsYann-Gaël Guéhéneuc
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingRichardWarburton
 
Java Generics Introduction - Syntax Advantages and Pitfalls
Java Generics Introduction - Syntax Advantages and PitfallsJava Generics Introduction - Syntax Advantages and Pitfalls
Java Generics Introduction - Syntax Advantages and PitfallsRakesh Waghela
 
standard template library(STL) in C++
standard template library(STL) in C++standard template library(STL) in C++
standard template library(STL) in C++•sreejith •sree
 
Java fundamentals
Java fundamentalsJava fundamentals
Java fundamentalsHCMUTE
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
 
Core java by a introduction sandesh sharma
Core java by a introduction sandesh sharmaCore java by a introduction sandesh sharma
Core java by a introduction sandesh sharmaSandesh Sharma
 
Introduction to Objective - C
Introduction to Objective - CIntroduction to Objective - C
Introduction to Objective - CJussi Pohjolainen
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Juan Pablo
 
Memory Management C++ (Peeling operator new() and delete())
Memory Management C++ (Peeling operator new() and delete())Memory Management C++ (Peeling operator new() and delete())
Memory Management C++ (Peeling operator new() and delete())Sameer Rathoud
 

Was ist angesagt? (20)

data Structure Lecture 1
data Structure Lecture 1data Structure Lecture 1
data Structure Lecture 1
 
Java generics final
Java generics finalJava generics final
Java generics final
 
Lecture06 methods for-making_data_structures_v2
Lecture06 methods for-making_data_structures_v2Lecture06 methods for-making_data_structures_v2
Lecture06 methods for-making_data_structures_v2
 
Java Generics for Dummies
Java Generics for DummiesJava Generics for Dummies
Java Generics for Dummies
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
On Parameterised Types and Java Generics
On Parameterised Types and Java GenericsOn Parameterised Types and Java Generics
On Parameterised Types and Java Generics
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional Programming
 
Java Generics Introduction - Syntax Advantages and Pitfalls
Java Generics Introduction - Syntax Advantages and PitfallsJava Generics Introduction - Syntax Advantages and Pitfalls
Java Generics Introduction - Syntax Advantages and Pitfalls
 
standard template library(STL) in C++
standard template library(STL) in C++standard template library(STL) in C++
standard template library(STL) in C++
 
Class method
Class methodClass method
Class method
 
iOS Session-2
iOS Session-2iOS Session-2
iOS Session-2
 
OOPs & Inheritance Notes
OOPs & Inheritance NotesOOPs & Inheritance Notes
OOPs & Inheritance Notes
 
C# Generics
C# GenericsC# Generics
C# Generics
 
Java fundamentals
Java fundamentalsJava fundamentals
Java fundamentals
 
C++11 - STL Additions
C++11 - STL AdditionsC++11 - STL Additions
C++11 - STL Additions
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Core java by a introduction sandesh sharma
Core java by a introduction sandesh sharmaCore java by a introduction sandesh sharma
Core java by a introduction sandesh sharma
 
Introduction to Objective - C
Introduction to Objective - CIntroduction to Objective - C
Introduction to Objective - C
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
Memory Management C++ (Peeling operator new() and delete())
Memory Management C++ (Peeling operator new() and delete())Memory Management C++ (Peeling operator new() and delete())
Memory Management C++ (Peeling operator new() and delete())
 

Ähnlich wie Lecture02 class -_templatev2

CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptx
CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptxCONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptx
CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptxDeepasCSE
 
Constructors and Destructors
Constructors and DestructorsConstructors and Destructors
Constructors and DestructorsKeyur Vadodariya
 
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13Abu Saleh
 
Operator Overloading
Operator OverloadingOperator Overloading
Operator OverloadingNilesh Dalvi
 
00-intro-to-classes.pdf
00-intro-to-classes.pdf00-intro-to-classes.pdf
00-intro-to-classes.pdfTamiratDejene1
 
Dynamic memory allocation in c++
Dynamic memory allocation in c++Dynamic memory allocation in c++
Dynamic memory allocation in c++Tech_MX
 
constructors.pptx
constructors.pptxconstructors.pptx
constructors.pptxEpsiba1
 
Constructor and Destructors in C++
Constructor and Destructors in C++Constructor and Destructors in C++
Constructor and Destructors in C++sandeep54552
 
FUNCTIONS, CLASSES AND OBJECTS.pptx
FUNCTIONS, CLASSES AND OBJECTS.pptxFUNCTIONS, CLASSES AND OBJECTS.pptx
FUNCTIONS, CLASSES AND OBJECTS.pptxDeepasCSE
 

Ähnlich wie Lecture02 class -_templatev2 (20)

CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptx
CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptxCONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptx
CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptx
 
Lecture 12: Classes and Files
Lecture 12: Classes and FilesLecture 12: Classes and Files
Lecture 12: Classes and Files
 
Constructors and Destructors
Constructors and DestructorsConstructors and Destructors
Constructors and Destructors
 
Operator overload rr
Operator overload  rrOperator overload  rr
Operator overload rr
 
Object Oriented Programming using C++ - Part 4
Object Oriented Programming using C++ - Part 4Object Oriented Programming using C++ - Part 4
Object Oriented Programming using C++ - Part 4
 
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
 
Link list
Link listLink list
Link list
 
w10 (1).ppt
w10 (1).pptw10 (1).ppt
w10 (1).ppt
 
Operator Overloading
Operator OverloadingOperator Overloading
Operator Overloading
 
00-intro-to-classes.pdf
00-intro-to-classes.pdf00-intro-to-classes.pdf
00-intro-to-classes.pdf
 
Dynamic memory allocation in c++
Dynamic memory allocation in c++Dynamic memory allocation in c++
Dynamic memory allocation in c++
 
constructors.pptx
constructors.pptxconstructors.pptx
constructors.pptx
 
Lecture5
Lecture5Lecture5
Lecture5
 
C++ idioms.pptx
C++ idioms.pptxC++ idioms.pptx
C++ idioms.pptx
 
C++ aptitude
C++ aptitudeC++ aptitude
C++ aptitude
 
Computer Programming- Lecture 10
Computer Programming- Lecture 10Computer Programming- Lecture 10
Computer Programming- Lecture 10
 
Constructor and Destructors in C++
Constructor and Destructors in C++Constructor and Destructors in C++
Constructor and Destructors in C++
 
Overloading
OverloadingOverloading
Overloading
 
FUNCTIONS, CLASSES AND OBJECTS.pptx
FUNCTIONS, CLASSES AND OBJECTS.pptxFUNCTIONS, CLASSES AND OBJECTS.pptx
FUNCTIONS, CLASSES AND OBJECTS.pptx
 
Javascript tid-bits
Javascript tid-bitsJavascript tid-bits
Javascript tid-bits
 

Mehr von Hariz Mustafa

Lecture04 polymorphism
Lecture04 polymorphismLecture04 polymorphism
Lecture04 polymorphismHariz Mustafa
 
Lecture03 inheritance
Lecture03 inheritanceLecture03 inheritance
Lecture03 inheritanceHariz Mustafa
 
Lecture01 object oriented-programming
Lecture01 object oriented-programmingLecture01 object oriented-programming
Lecture01 object oriented-programmingHariz Mustafa
 
Topic6decisionmaking
Topic6decisionmakingTopic6decisionmaking
Topic6decisionmakingHariz Mustafa
 
Topic5cognition and problem_solving
Topic5cognition and problem_solvingTopic5cognition and problem_solving
Topic5cognition and problem_solvingHariz Mustafa
 
Problem solving activities
Problem solving activitiesProblem solving activities
Problem solving activitiesHariz Mustafa
 
Exercise answers chapter 1, 2 & 3
Exercise answers chapter 1, 2 & 3Exercise answers chapter 1, 2 & 3
Exercise answers chapter 1, 2 & 3Hariz Mustafa
 
Decision making scenarios
Decision making scenariosDecision making scenarios
Decision making scenariosHariz Mustafa
 
Cognition and problem_solving
Cognition and problem_solvingCognition and problem_solving
Cognition and problem_solvingHariz Mustafa
 
Chapter 6 logical_fallacies_ii
Chapter 6 logical_fallacies_iiChapter 6 logical_fallacies_ii
Chapter 6 logical_fallacies_iiHariz Mustafa
 
Ch08 evaluating arguments
Ch08 evaluating argumentsCh08 evaluating arguments
Ch08 evaluating argumentsHariz Mustafa
 
Chapter 5 logical_fallacies_i
Chapter 5 logical_fallacies_iChapter 5 logical_fallacies_i
Chapter 5 logical_fallacies_iHariz Mustafa
 
Ch03 basic logical_concepts
Ch03 basic logical_conceptsCh03 basic logical_concepts
Ch03 basic logical_conceptsHariz Mustafa
 

Mehr von Hariz Mustafa (20)

Lecture10 trees v3
Lecture10 trees v3Lecture10 trees v3
Lecture10 trees v3
 
Lecture09 recursion
Lecture09 recursionLecture09 recursion
Lecture09 recursion
 
Lecture04 polymorphism
Lecture04 polymorphismLecture04 polymorphism
Lecture04 polymorphism
 
Lecture03 inheritance
Lecture03 inheritanceLecture03 inheritance
Lecture03 inheritance
 
Lecture01 object oriented-programming
Lecture01 object oriented-programmingLecture01 object oriented-programming
Lecture01 object oriented-programming
 
Topic6decisionmaking
Topic6decisionmakingTopic6decisionmaking
Topic6decisionmaking
 
Topic5cognition and problem_solving
Topic5cognition and problem_solvingTopic5cognition and problem_solving
Topic5cognition and problem_solving
 
Topic2 argument
Topic2 argumentTopic2 argument
Topic2 argument
 
Topic2
Topic2Topic2
Topic2
 
Topic 1
Topic 1Topic 1
Topic 1
 
Problem solving activities
Problem solving activitiesProblem solving activities
Problem solving activities
 
Exercise answers chapter 1, 2 & 3
Exercise answers chapter 1, 2 & 3Exercise answers chapter 1, 2 & 3
Exercise answers chapter 1, 2 & 3
 
Decision making scenarios
Decision making scenariosDecision making scenarios
Decision making scenarios
 
Decision making
Decision makingDecision making
Decision making
 
Cognition and problem_solving
Cognition and problem_solvingCognition and problem_solving
Cognition and problem_solving
 
Chapter 6 logical_fallacies_ii
Chapter 6 logical_fallacies_iiChapter 6 logical_fallacies_ii
Chapter 6 logical_fallacies_ii
 
Chapter 4 language
Chapter 4 languageChapter 4 language
Chapter 4 language
 
Ch08 evaluating arguments
Ch08 evaluating argumentsCh08 evaluating arguments
Ch08 evaluating arguments
 
Chapter 5 logical_fallacies_i
Chapter 5 logical_fallacies_iChapter 5 logical_fallacies_i
Chapter 5 logical_fallacies_i
 
Ch03 basic logical_concepts
Ch03 basic logical_conceptsCh03 basic logical_concepts
Ch03 basic logical_concepts
 

Lecture02 class -_templatev2

  • 1. Class & Template Lecture 2 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 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). TCP1201 OOPDS
  • 4. Dangling Pointer • Is pointer that does not point to an valid address. • Use of dangling pointer generates runtime error easily. int* p; // 'p' usually does not point to // a valid address. *p = 10; // Runtime error usually. ? p [ int* ] TCP1201 OOPDS
  • 5. Point to Existing Data Without Cloning the Data 1432 3 a [ int ] int a = 3; int *p = &a; 4324 1432 p [ int* ] cout << *p; // 3 cout << p; // 1432 'a' stores an int . 'p' stores The ampersand '&' is the address of variable 'a'. called address operator which returns the We say 'p' points to 'a'. address of variable 'a'. 'p' is not a clone of 'a'. TCP1201 OOPDS
  • 6. Dynamic Memory Allocation (DMA) • 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. 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. TCP1201 OOPDS
  • 7. Dynamic Memory Allocation (DMA) 1432 ? • Use delete [] to release the 1432 p1 [ int* ] [int] memory used by a dynamic array. 1100 1100 ? [int] p2 [int* ] 1104 ? [int] int* p1 = new int; // Create 1 int. 1108 delete p1; // Release 1 int. ? [int] 1112 ? [int] int* p2 = new int[4]; // Create a dynamic // array of 4 int. delete [] p2; // Release dynamic array. TCP1201 OOPDS
  • 8. 4 Types of Object Behaviors 1. 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. 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. } 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 TCP1201 OOPDS
  • 11. 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; ... TCP1201 OOPDS
  • 12. Without Default Constructors • If you do not provide both default constructor and overloaded constructor, C++ automatically creates a default constructor with blank implementation. // Your code class Student { // No default constructor or // overloaded constructor is provided. int id; string name; }; // Compiler code class 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 = ? ... TCP1201 OOPDS
  • 13. Constructor Initializer List • 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> { ... } Constructor name Colon Constructor body Initializer list ClassName (datatype1 param1, datatype2 param2) : attribute1 (param1), attribute2 (param2) { ... } TCP1201 OOPDS
  • 14. 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. ... TCP1201 OOPDS
  • 15. 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). TCP1201 OOPDS
  • 16. Example: Default Constructor class Student { Output: int id; string name; A Student object is created! public: Student id = 0 Student() // Default constructor Student name = "Unknown" : id(0), name("Unknown") { Student id = 123 cout << "A Student object is created!n"; Student name = "Ali" } 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; } TCP1201 OOPDS
  • 17. 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" ... TCP1201 OOPDS
  • 18. 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 ... TCP1201 OOPDS
  • 19. 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". ... 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". TCP1201 OOPDS
  • 21. Copy Constructors • A class can have one copy constructor only. • Copy constructor must have the following header/interface/signature: Parameter name refers to the source instance that is being “copied” Parameter is of the same type as the class ClassName (const ClassName& existingInstance); Pass by reference to avoid cloning the parameter const prevents existing instance from being modified by the copy constructor Student (const Student& existingStudent); 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. { } }; 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. 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. TCP1201 OOPDS
  • 25. Problem: Shallow copy a pointer attribute in Copy Constructor class Student { int main() { int size; Student *s1, *s2; double *marks; // Pointer attribute. s1 = new Student (3); public: s2 = new Student (*s1); Student (int size); // Overloaded constructor. s1->print(); // 0 0 0 // No copy constructor is written, C++ provides one. s2->print(); // 0 0 0 void setMark (int index, int mark); s1->setMark (0, 70); void print(); s1->setMark (1, 80); }; s1->setMark (2, 90); Student::Student (int size) s1->print(); // 70 80 90 : size(size) { s2->print(); // 70 80 90 this->marks = new double[size]; // Create dynamic array. delete s1; for (int i = 0; i < size; i++) delete s2; marks[i] = 0; } } void Student::setMark (int index, int mark) { marks[index] = mark; Output: } Marks = 0 0 0 void Student::print() { Marks = 0 0 0 cout << "Marks = "; for (int i = 0; i < size; i++) Marks = 70 80 90 cout << marks[i] << " "; Marks = 70 80 90 cout << endl; } s2 points to s1's marks array, hence sharing one marks array TCP1201 OOPDS
  • 26. Solution: Deep copy in Copy Constructor class Student { int main() { int size; Student *s1, *s2; double *marks; // Pointer attribute. s1 = new Student (3); public: s2 = new Student (*s1); Student (int size); // Overloaded constructor. s1->print(); // 0 0 0 Student (const Student& s); // Copy constructor. s2->print(); // 0 0 0 void setMark (int index, int mark); s1->setMark (0, 70); void print(); s1->setMark (1, 80); }; s1->setMark (2, 90); Student::Student (int size) s1->print(); // 70 80 90 : size(size) { s2->print(); // 0 0 90 this->marks = new double[size]; // Create dynamic array. delete s1; for (int i = 0; i < size; i++) delete s2; marks[i] = 0; } } Student::Student (const Student& s) // Copy constructor. : size(s.size) { Output: this->marks = new double[size]; // Create dynamic array. Marks = 0 0 0 for (int i = 0; i < size; i++) Marks = 0 0 0 marks[i] = s.marks[i]; // Copy array. } Marks = 70 80 90 void Student::setMark (int index, int mark) { Marks = 0 0 0 marks[index] = mark; } void Student::print() { cout << "Marks = "; s1 and s2 each have a for (int i = 0; i < size; i++) cout << marks[i] << " "; different marks array cout << endl; } 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(); }; 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 example class Student { double *marks; // Pointer attribute. public: ... ~Student(); }; Student::~Student() { delete [] marks; // Destroy dynamic attribute. } 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. // Your code class Student { // No destructor is provided. }; // Compiler code class Student { public: -Student() { // Compiler's default destructor, // blank implementation. } }; TCP1201 OOPDS
  • 30. Example: Destructor class Student { int id; Output: public: Student(int id); // constructor Object 000 created. ~Student(); // destructor Object 000 destroyed. }; Object 111 created. Student::Student(int id) Object 222 created. : id(id) { Object 333 created. cout << "Object " << id << " created.n"; Object 222 destroyed. } Object 111 destroyed. 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;" 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; } }; 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; } }; 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 } } TCP1201 OOPDS
  • 34. Update & Query Behaviors • Identify the type of behaviors of the Student class on the right. • Query behaviors: Student – getId, show_subjects. -id: int • Update behaviors: -subjects:string[*] +getId():int – register_subject (modify attribute +setId(id:int):void subjects). +show_subjects():void – withdraw_subject (modify attribute +register_subject():void +withdraw_subject():void subjects). 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. ... } 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 class int Student::count = 0; // Initialize count to 0. 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. TCP1201 OOPDS
  • 38. Example: static Members class Student { int main() { string name; cout << "Student count = " static int count; << Student::getCount() << endl; public: Student a; // create 1 instance Student() { ++count; } cout << "Student count = " ~Student() { --count; } << a.getCount() << endl; static int getCount() { Student* b = new Student; // create 1 instance. return count; cout << "Student count = " } << b->getCount() << endl; }; { int Student::count = 0; Student c; // create 1 instance. cout << "Student count = " << c.getCount() << endl; } // c is destroyed delete b; // b is destroyed. cout << "Student count = " Output: << Student::getCount() << endl; // Why not zero? Student count = 0 } Student count = 1 Student count = 2 Student count = 3 Student count = 1 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; } 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. 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; } }; 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. TCP1201 OOPDS
  • 43. Function Template • To swap 2 integers, we may write the following function: void Swap (int& m, int& n) { int temp = m; m = n; n = temp; } • To swap 2 strings, we need to write another function: void Swap (string& s1, string& s2) { string temp = s1; s1 = s2; s2 = temp; } The only different between these 2 functions are data type. Template is the best solution. TCP1201 OOPDS
  • 44. Function Template Example • Template version of Swap function: template <typename T> Compiler produces 2 void Swap(T& x, T& y) { definitions of T temp = x; Swap() functions: x = y; y = temp; one for int, one for } string. int main() { Output: int m = 22, n = 66; Swap(m, n); // integers m = 66 cout << "m = " << m << endl n = 22 << "n = " << n << endl; s1 = Kelly string s1 = "Michael", s2 = "Kelly"; s2 = Michael Swap(s1, s2); // strings cout << "s1 = " << s1 << endl << "s2 = " << s2 << endl; } 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: template <typename T> // Less confusing, or template <class T> // more confusing, class? • 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, typename U, typename V> 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: template <typename T> class Box { T data; ... • A class template may have several type parameters: template <typename T, typename U> class Box { T data1; U data2; ... }; TCP1201 OOPDS
  • 47. Class Template Example 1 Define a class template int main() { Pair<int> p1; Pair that have 2 attributes p1.set (3,5); of the same type. Pair<string> p2; p2.set ("Peter", "Jackson"); template <typename T> Pair<char> *p3 = new Pair<char>; class Pair { p3->set ('P','J'); T a; cout << p1.getA() << " " T b; << p1.getB() << endl public: << p2.getA() << " " << p2.getB() << endl void set (T a, T b) { << p3->getA() << " " this->a = a; << p3->getB(); this->b = b; delete p3; } } T getA() { return a; } Output: T getB() { return b; } 3 5 }; Peter Jackson TCP1201 OOPDS J P
  • 48. Class Template Example 1 Class template allows us to int main() { Pair<int> p1; write one class that works p1.set (3,5); with different data types. Pair<string> p2; p2.set ("Peter", "Jackson"); template <typename T> Pair<char> *p3 = new Pair<char>; class Pair { p3->set ('P','J'); T a; cout << p1.getA() << " " T b; << p1.getB() << endl public: << p2.getA() << " " << p2.getB() << endl void set (T a, T b) { << p3->getA() << " " this->a = a; << p3->getB(); this->b = b; delete p3; } } T getA() { return a; } Output: T getB() { return b; } 3 5 }; Peter Jackson TCP1201 OOPDS J P
  • 49. Class Template Example 2: Multiple Type Parameters Attributes may have int main() { Pair<int,char> p1; different data types. p1.set (1, 'A'); Pair<char,string> p2; template <typename T, p2.set ('B',"Boy"); typename U> Pair<int,int> *p3 = new class Pair { Pair<int,int>; T a; p3->set (99,99); cout << p1.getA() << " " U b; << p1.getB() << endl public: << p2.getA() << " " void set (T a, U b) { << p2.getB() << endl this->a = a; << p3->getA() << " " << p3->getB(); this->b = b; delete p3; } } T getA() { return a; } U getB() { return b; } Output: 1 A }; B Boy TCP1201 OOPDS 99 99
  • 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. 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; } TCP1201 OOPDS