Computational Intelligence on Automation Lab @ NCTU                          Learning Objectives
You should be able to understand:
                           UEE1303(1070) S’12                                  Object and pointer
                                                                                 –dynamical memory for objects
                                Object-Oriented                                  –pointers to methods and members
                           Programming in C++                                    –this pointer
                                                                               Different kinds of data members and methods
                                                                                 –const data and methods
                                       Lecture 04:                               –mutable and explicit members
                   Classes (II) – Advanced Topics                              Advanced composition
                                                                                 –Nested classes
                                                                               Friend function and class
                                                                        Leture 04                 UEE1303(1070)                  2
                   Objects and Pointers                                                        Object Array
       C++ expands dynamic allocation to objects                              Similar to struct arrays, class can be used to
         –allow malloc()/free() and new/delete                                  create object arrays
         – malloc() does not call the constructor                                –format: 〈CName〉 〈pObj〉[iSize];
           when an object is created                                             –use public member: 〈pObj〉[iIdx].member;
         –Use new/delete for objects                                           Example: lec4-1.cpp (part 1)
       Heap objects                                                                CScore StuAry[3];
                                                                                    //CScore[0]=(“Adam”,{43,62,85});
         –Format:                                                                   //CScore[0]=(“Bill”,{72,82,93});
            〈CName〉 * 〈pObj〉 = new 〈CName〉;                                         //CScore[0]=(“Nick”,{31,53,76})};
            delete 〈pObj〉;                                                          double sum = 0;
            –Ex:                                                                    for (int i=0; i<3; i++) {
            CScore * pStu = new CScore;                                                 sum += StuAry[i].computeAverage();
            pStu->computeAverage();                                                 }
            delete pStu;                                                            cout << sum/3.0 << endl;
Leture 04                       UEE1303(1070)                       3   Leture 04                 UEE1303(1070)                  4
            Pointer to Member Function (1/2)                              Pointer to Member Function (2/2)
       Pointer to normal functions (in Lecture 02)                Pointer to member functions
                                                                         〈datatype〉 (〈CName〉 ::*〈pFun〉)(para_list);
         –Format: 〈rtn_type〉 (*〈pFun〉)(〈para_list〉);
                                                                         –Ex: double (CScore::* pF)();
         –Ex:
                 double (*pF)();                                              ...
                 ...                                                          pF = &CScore::computeAverage;
                 pF = Fun;                                         Use the pointer to the member function, Ex:
                 double result = (*pF)();                                //lec4-1.cpp (part 2)
                                                                         CScore * p1 = &(StuAry[2]);
       What if ? pF = &StuAry[0].computeAverage;                        cout << p1->computeAverage();
         –compilation error!                                             double (CScore::* p2)() =
         –because the return type of the pointer                                 &CScore::computeAverage;
                                                                         cout << (p1->*p2)();
         should match the type of member function
                                                                         –member functions are not put at the space
         –double is not equal to CScore::double
                                                                         of objects but that all class objects share
Leture 04                   UEE1303(1070)                5   Leture 04                   UEE1303(1070)                 6
                 Pointer to Data Member                                           this Pointer (1/3)
       Similar to the pointer to member function, the            How C++ guarantee that the data member is
        pointer to data member has the format                      correctly referenced via member function?
            〈datatype〉 (〈CName〉::* 〈pName〉);                      Example:
            〈pName〉 = &〈CName〉::〈data_member〉;
                                                                         class Box {
       Ex: see more in lec4-1.cpp(part 3)                               public:
            class X {                                                        Box(int h=6, int w=8, int l=10):
            public:                                                              hgt(h), wid(w), len(l) {}
                int a;                                                       int vol() { return hgt*wid*len; }
                void f(int b) { cout << b << endl;}                      private:
            };                                                               int hgt, wid, len;
            int X::* pa = &X::a;                                         };
            X obj1;                                                      Box a(2,4,6), b(3,5,7);
            obj1.*pa = 10;
            cout << “value a = ” << obj1.*pa;                            – a.vol() and b.vol() use the same function
Leture 04                   UEE1303(1070)                7   Leture 04                   UEE1303(1070)                 8
                      this Pointer (2/3)                                                 this Pointer (3/3)
     Each member function contains a special                            Explicitly use this pointer if needed
      pointer named this                                                        //in Box class declaration, version 1
       –points to the address of the called object                              int vol() {
            (this->hgt)*(this->wid)*(this->len);                                    return ((*this).hgt)*((*this).wid)
                                                                                *((*this).len); }
            –If call a.vol(), equivalently,
            (a->hgt)*(a->wid)*(a->len);                                         –pair of parentheses cannot be omitted
            – this pointer is used implicitly but works like
                                                                                 because dot (.) operator precedes
            //in Box class declaration, version 2                                dereference (*) operator
            int vol(Box * this) {                                               –If *this.hgt is interpreted as *(this.hgt)
                 return (this->hgt)*(this->wid)                                   but this is a pointer and this.hgt cannot
            *(this->len); }
            and call by                                                          be parsed correctly
            a.vol(&a);                                                            Compilation error!  use this->hgt
Leture 04                     UEE1303(1070)                    9    Leture 04                   UEE1303(1070)              10
              Example of this Pointers (1/2)                                      Example of this Pointers (2/2)
class CPoint {                                                      class CPoint {
    int x, y;                                                       public:
public:                                                                 CPoint offset(int diff) {
    //this is hidden in setPt() and Print()                                 x += diff; y += diff;
    void setPt(int c, int d) { x=c; y=d; }                                  return *this; //real use of this
    void Print() { cout << x << “ ”                                     }
                        << y << endl; }                             };
};
                                                                    //in main()
class CPoint {                                                      CPoint p, q;
    int x, y;                                                       int a=3, b=5;
public:                                                             p.setPt(a,b);
    //use this to refer the current object                          p.Print();
    void setPt(int x, int y) {                                      q = p.offset(3);
        this->x=x; this->y=y; }                                     q.Print();
    void Print() { cout << this->x << “ ”                           p.Print();                   What are going to be printed
                        << this->y << endl; }                                                    on screen?
};
Leture 04                     UEE1303(1070)                    11   Leture 04                   UEE1303(1070)              12
             Summarize this Pointer                                      Different Kinds of Members
       A this pointer stores the address of an object        C++ has many choices of members
        used to call a non-static member function               – static members: members that all objects
         –typically hidden from programmer                        of that class share
         –handled by the compiler
                                                                – const members: members that require
         –address of that object is passed to the
                                                                  initialization and cannot be updated
          function and stored in this
         –access the data stored in the object by               – mutable members : members that need no
          dereferencing this, i.e. this->[member]                 protection from changing any time but are
         –use when returning the object itself or when            encapsulated in class
          parameters have the same name as private              – explicit members: members that avoid
          data members                                            ambiguity from calling constructor implicitly
         be aware of this for advanced OOP                     –and more (reference members)
Leture 04                UEE1303(1070)               13   Leture 04                  UEE1303(1070)                14
                Static Data Members                                      Define Static Data Members
       Class provides data encapsulation and hiding             A static data member is defined by
         –but results in difficulties data sharing and             –use keyword static to declare a data
           external visit                                           member in class
         –can be resolved by global variables                      –allocate memory and initialize outside class
       A better solution  static members                         –not limited by the access modifier
         –is specific to one class                               Example
         –has a scope shared by the objects of the                    class X {
           same class                                                 private:
       A static member can be accessed                                   //declare a static data variable
                                                                          static int count;
         (1) with class methods or                                    };
         (2) outside class methods                                    //mtd(1): initialize the static member
            〈type〉 〈class〉::〈static_data〉 = 〈value〉;                  int X::count = 0;
Leture 04                UEE1303(1070)               15   Leture 04                  UEE1303(1070)                16
            Access with Class Methods                                 Use Static Members (1/3)
       Use static data members from class methods             Design a CScore class with data members: id
class CNum {                                                    number (id), name (name), three subject scores
public:
    CNum(int a) { x = a; y += x; }                              (subj[3]) , and total sum of each subject
    static void fun(CNum m) {                                   scores (sum[3]). Write functions to compute the
        cout << m.x << “vs.” << y << endl; }                    sums of each subjects.
private:
    int x;                                                    //lec4-3.cpp (part 1)
                                                              class CScore //data members in CScore
    static int y;                                             {
};                                                            private:
int CNum::y = 0;                                                  char id[6];
//in main()                                                       char name[20];
CNum O1(4), O2(7);                                                int subj[3];
CNum::fun(O1);                                                    static int sum[3];
CNum::fun(O2);       What to display on screen?               }
Leture 04              UEE1303(1070)                 17   Leture 04               UEE1303(1070)              18
             Use Static Members (2/3)                                 Use Static Members (3/3)
//member functions for CScore                             //Constructor for CScore objects
public:                                                   CScore::CScore(char *uid, char *uname,
    CScore(char *, char *, int *);                                       int *uscore) {
    void showSCore() {                                         subj[0] = uscore[0];
        cout << id << “ ” << name << “ ”                       subj[1] = uscore[1];
        << subj[0] << “ ” << subj[1] << “ ”                    subj[2] = uscore[2];
        << subj[2] << endl;                                    strcpy(id, uid); strcpy(name, uname);
    }                                                          sum[0] += subj[0];
    static void showSum() {                                    sum[1] += subj[1];
        cout << sum[0] << “ ” << sum[1] <<                     sum[2] += subj[2];
        “ ” << sum[2] << endl;                            }
    }                                                     //in main(){}
};                                                        //CScore S1(“99123”, “Tom”, {70, 80, 90});
int CScore::sum[3] = {0,0,0};                             S1.showSCore(); S1.showSum();
//or int CScore::sum[3];                                  //CScore S2(“99145”, “Bill”, {60, 40, 50});
                                                          S2.showSCore(); S2.showSum();
Leture 04              UEE1303(1070)                 19   Leture 04               UEE1303(1070)              20
               const Members (1/2)                                            const Members (2/2)
       Constants almost never make sense at the                 const can used with & modifier  need to be
        object level  often used with static modifier                initialized in constructors
class CScore { //lec4-3.cpp (part 2)                      class CScore { //lec4-3.cpp (part 2)
protected:                                                public:
    //declare a static constant                               //declare a constant reference
    static const int Max;                                     const int & sc;
};                                                        };
const int CScore::Max = 100; //outside class
                                                          //modified constructor in CScore
//modified constructor in CScore                          CScore::CScore(char *uid, char *uname,
CScore::CScore(char *uid, char *uname,                        int *uscore) : sc(subj[0])    {
                   int *uscore) {                             subj[0] = (uscore[0]>Max)?Max:uscore[0];
    subj[0] = (uscore[0]>Max)?Max:uscore[0];                  subj[1] = (uscore[1]>Max)?Max:uscore[1];
    subj[1] = (uscore[1]>Max)?Max:uscore[1];                  subj[2] = (uscore[2]>Max)?Max:uscore[2];
    subj[2] = (uscore[2]>Max)?Max:uscore[2];              ...}
...}
Leture 04                UEE1303(1070)               21   Leture 04                      UEE1303(1070)          22
                   const Methods                                            mutable Data Members
       Only constant methods can call a const                 mutable means volatile  constant
        object or a reference to const object                    –a constant function cannot modify any data
    class CScore {                                                member which may not need protection
    public: //add more const methods                           mutable makes data member always
        char* getName() const { return name; }                  changeable, even in a const method
        void setName(const char* uname) {
            strcpy(name, uname);} //not const                    –cannot modify methods but regular variables
    };                                                           –can modify const and static, not reference
   //CScore S1(“99123”, “Tom”, {70, 80, 90});                   class CScore {//lec4-3.cpp (part 3)
   cout << S1.getName() << endl; //OK!                          public:
   S1.setName(“Tom Mitchell”); //OK!                                mutable int sCount = 0;                };
   const CScore & S3 = S1;
   cout << S3.getName() << endl; //OK!                          void CScore::showName() const {
   S3.setName(“Bob”); //compilation error!                          cout<<sCount++<<“:”<<name<<endl;       }
Leture 04                UEE1303(1070)               23   Leture 04                      UEE1303(1070)          24
              More on mutable Members                                        explicit Members
       Modify mutable data by constant objects                  Two types of calling constructors:
       class COne {                                                –explicit call 〈CName〉 〈Obj〉(〈init_values〉);
       public:                                                     –implicit call 〈CName〉 〈Obj〉 = 〈init_values〉;
           mutable int x; int y;                      };
                                                                 Distinguish implicit call and object assignment?
       const COne m;                                           CScore::CScore(const char* cstr) {
       m.x = 10; //legally used                                    cout << cstr << endl;
       m.y = 20; //not legally used                            }
       const + mutable: leave for self-exploration            CScore one = “Tom”; //assign or construct?
       class CTwo {                                             explicit is used to modify constructors of a
           //good: ptr to a mutable constant                        class and use them explicitly
           mutable const int* p;                               explicit CScore::CScore(const char* cstr)
           //bad: a mutable constant pointer                   { ... }
           mutable int* const q;                      };       CScore one = “Tom”; //illegal now!!
Leture 04                  UEE1303(1070)               25   Leture 04                 UEE1303(1070)              26
                Advanced Composition                                      Example of Nested Class
       Nested class : a class CTwo is declared within      class Node { ... }; //outer class
        the scope of another class COne                     class Graph {
                                                            public:
         –used when the inner class is meaningful               //Graph::Node hides ::Node in Graph’s {}
           inside the outer class                               class Node { ... }; //inner class
                                                                //resolves to nested Graph::Node
         –if CTwo is public, use with COne::                    Node *grpah;
         –format: class COne { //outer class                };
                         ...                                //Graph::Node is not visible globally
                         class CTwo { //inner class         Node *pnode;
                                                            class Chain {
                             ...                            public:
                         };                                     //Chain::Node hides ::Node in Chain’s {}
                    };                                          class Node { ... }; //inner class
            –Nested class cannot access any private             //resolves to nested Chain::Node
                                                                Node *chain;
             member of the outer class by default           };
Leture 04                  UEE1303(1070)               27   Leture 04                 UEE1303(1070)              28
              More on Nested Classes                                     Defined Outside Outer Class
       A nested class CTwo in COne can have the                    A nested class can also be defined outside
        same kind of members as a nonnested class                    the enclosing class
         –Example:                                                    –need to take care of qualifier
class Chain { //outer class                                           –only pointers and references to the inner
public:                                                                 class can be declared
    class Item { //all members are private                          class COne { //enclosing class
        friend class Chain;                                             class CTwo; //nested class
        Item(int val = 0); //constructor                                CTwo *pobj; //CTwo obj is wrong!!!
        Item *next; //point to its own class
        int val;                                                        //...
    };                                                              };
    //...                                                           class COne::CTwo {
private:                                                                CTwo(int val=0);
    Item *chain;                                                        CTwo *next;
    Item *at_end;                                                       int value;
};                                                                  };
Leture 04                UEE1303(1070)                  29   Leture 04                UEE1303(1070)                30
            Later Definition of Inner Class                                    friend Functions
       A nested class can be first declared and then               Hiding data inside a class and letting only
        later defined in the outer class                             class member functions have direct access to
                                                                     private data is a very important OOP concept
class Chain { //outer class                                         But C++ also provides another of function to
private:
    class Item; //declare Chain::Item                                access members in class  friend functions
    class Ref {                                                       – friend functions are not member functions
        Item *pIt; //has type Chain::Item*
    };                                                                  but can still access class private members
    class Item { //later define Chain::Item                           –defined outside of class scope
        Ref *pref; //has type Chain::Ref*                           Reasons to have friend functions:
    };
    //...                                                             –to access private members of two or more
};                                                                      different classes
                                                                      –for I/O or operator (in Lecture 6) functions
Leture 04                UEE1303(1070)                  31   Leture 04                UEE1303(1070)                32
            Properties of friend Functions                             Example of friend Functions
                                                           //lec4-4.cpp
       Properties:                                        class CPoint {
          –placed inside the class definition and              int x, y;
            preceded by the friend keyword                     friend CPoint offset(CPoint &, int);
                                                           public:
          –defined outside the class as a normal, non-         CPoint() { x=0; y=0; }
            member function                                    CPoint(int a, int b) { x=a; y=b; }
                                                               void Print() { cout << x << “ ”
          –called like a normal non-member function.                               << y << endl; }
       If a function is a friend of two or more           };
                                                           CPoint offset(CPoint &pt, int diff) {
        different classes, each class must contain the         pt.x += diff; pt.y += diff;
        friend function prototype within its body              return pt;
                                                           }
       A friend function cannot be inherited (covered
                                                           //in main()
        in Lecture #7) but can be a member of one          CPoint p1( 3, 5 ); p1.Print();
        class                                              offset(p1, 4); p1.Print();
Leture 04                UEE1303(1070)                33   Leture 04              UEE1303(1070)        34
                   friend Classes                                      Example of friend Class (1/3)
       An entire class can be a friend of another         //in CPoint.h
                                                           class CPoint {
        class  friend class                                   friend class CLine;
         –can be used when all member functions of             int x, y;
                                                               void Offset(int diff) {
           one class should access the data of                     x += diff; y += diff;
           another class                                       }
                                                           public:
         –require prototypes to be placed within each          CPoint() { x=0; y=0; }
           class individually                                  CPoint(int a, int b) { x=a; y=b; }
       An entire class can be designed as friend              void set(int a, int b) {
                                                                   x=a; y=b;
         –all its member functions automatically               }
           granted a friendship by the class                   void Print() {
                                                                   cout << x << “ ” << y << endl;
         –but “class B is a friend of class A” does not        }
           imply “class A is a friend of class B”          };
Leture 04                UEE1303(1070)                35   Leture 04              UEE1303(1070)        36
            Example of friend Class (2/3)                            Example of friend Class (3/3)
//in CLine.h                                           //in main()
class CLine {                                          #include “CPoint.h”
    CPoint p1, p2;                                     #include “CLine.h”
public:
    CLine(int x, int y, int w, int z) {                int main()
        p1.x = x; p1.y = y; //access private           {
        p2.x = w; p2.y = z;           }                    CPoint p1(2,4); p2(6,8);
    void Print()() {                                       p1.Print(); p2.Print();
        //call public Print in CPoint                      p1.Offset(3); //error! Why?
        cout << “Point 1:”; p1.Print();
        cout << “Point 2:”; p2.Print(); }                          CLine l1(1,3,5,7), l2(2,4,6,8);
    void Display() {                                               l1.Print();
        offset(p1,100); //call friend func                         l2.Display();
        p2.Offset(200); //call private func
        Print(p1, p2); }                                           return 0;
};                                                     }
Leture 04               UEE1303(1070)             37   Leture 04                  UEE1303(1070)                38
                   Summary (1/2)                                               Summary (2/2)
       Review object and pointers with class:                Advanced composition
         –What is object array?                                  –What is a nested class and a enclosing
         –How to use pointers to members in class?                 class?
         –this pointers                                          –Can a nested class include a member of
       Different kinds of Members                                 the same kind?
                                                                 –How to define the nested class outside the
         –What is a static data member?
                                                                   enclosing class?
         –Why do we need const methods?                          –How to access the public and private
         –What is a mutable data member? Why do                    member of outer class?
           we need mutable                                    friend
         –What is a explicit members? When to apply              –When to use a friend function?
           explicit?                                             –When to use a friend class and how?
Leture 04               UEE1303(1070)             39   Leture 04                  UEE1303(1070)                40