2009年1月31日

C++ Operator overloaded

Operator overloaded是C++獨特的功能,能夠把operator重新定義,符合class的需求,但是在定義的時候要注意是否違反class原本的意義。

  • Rule of thumb, if a class needs a destructor, it will also need the assignment  operator and a copy constructor. C++ Primer P.485
  • If the operator often does the same work, the common work should be put in private utility functions.
  1. #include <iostream>
  2. #include <cstdlib>
  3. using namespace std;
  4. //////////////////////////////////////////////////////
  5. class Point{
  6. public:
  7.     //constructor
  8.     Point(double xval=0.0, double yval=0.0):
  9.         x(xval), y(yval){}
  10.  
  11.     //copy constructor
  12.     Point(const Point &rhs):
  13.         x(rhs.x), y(rhs.y){}
  14.  
  15.     //destructor
  16.     ~Point(){}
  17.  
  18.     //must return a new object
  19.     friend Point
  20.     operator+ (const Point &lhs, const Point &rhs){
  21.         Point ret(lhs);
  22.         //call overloaded operator +=
  23.         ret += rhs;
  24.         return ret;
  25.     }
  26.  
  27.     //must return reference
  28.     Point& operator+= (const Point &rhs){
  29.         this->x += rhs.x;
  30.         this->y += rhs.y;
  31.         return *this;
  32.     }
  33.  
  34.     //prefix operator,return a reference
  35.     Point& operator++ (){
  36.         this->x += 1.0;
  37.         this->y += 1.0;
  38.         return *this;
  39.     }
  40.  
  41.     //posfix operator++, return a new object
  42.     Point operator++(int){
  43.         Point ret(*this);
  44.         ++*this;
  45.         return ret;
  46.     }
  47.  
  48.     friend inline bool
  49.     operator== (const Point &lhs, const Point &rhs){
  50.         return lhs.x == rhs.x && lhs.y == rhs.y;
  51.     }
  52.  
  53.     friend inline bool
  54.     operator!= (const Point &lhs, const Point &rhs){
  55.         return !(lhs == rhs);
  56.     }
  57.  
  58.     //input operators must deal with errors and EOF
  59.     friend istream&
  60.     operator>> (istream &in, Point &obj){
  61.         in>>obj.x>>obj.y;
  62.         if(!in)
  63.             obj = Point();
  64.         return in;
  65.     }
  66.  
  67.     //IO operators must be nomember functions
  68.     //should not print a newline
  69.     friend ostream&
  70.     operator<< (ostream &os, const Point &obj){
  71.         os<<"("<<obj.x<<", "<<obj.y<<")";
  72.         return os;
  73.     }
  74.  
  75. private:
  76.     double x, y;
  77. };
  78. //////////////////////////////////////////////////////
  79.  

2009年1月30日

C++ Class基本架構

常常在使用C++ Class,但是常常會忘記架構,以下使用個簡單的範例來展示class的基本結構。

  1. #include <iostream>
  2. #include <string>
  3. #include <cstdlib>
  4. using namespace std;
  5. ////////////////////////////////////////////////////
  6. class Base
  7. {
  8. public:
  9.     //constructor
  10.     Base(int num=0,string str=""):
  11.         base_id(num), base_name(str){
  12.         cout<<"Base construction\n";
  13.     }
  14.  
  15.     //Destructor
  16.     //若Base class的destructor沒有設定為virtual
  17.     //則derived clss的destructor不會被呼叫,無法運作
  18.     virtual ~Base(){
  19.         cout<<"Base destroyed\n";
  20.     }
  21.  
  22.     //overloading
  23.     virtual void print(){
  24.         cout<<"base id = "<<base_id
  25.             <<" name = "<<base_name<<endl;
  26.     }
  27.  
  28.     //abstract method, 必須是virtual,否則無法compile
  29.     virtual void printall() = 0;
  30.  
  31. protected:
  32.     int base_id;
  33.     string base_name;
  34. };
  35. ////////////////////////////////////////////////////
  36. class Derived : public Base
  37. {
  38. public:
  39.     //constructor
  40.     Derived(int num=0, string str="", int val=0):
  41.         Base(num, str), derived_id(val){
  42.         cout<<"Derived construction"<<endl;
  43.     }
  44.  
  45.     //Destructor
  46.     virtual ~Derived(){
  47.         cout<<"Derived destroyed\n";
  48.     }
  49.  
  50.     virtual void print(){
  51.         cout<<"derived id = "<<derived_id<<endl;
  52.     }
  53.  
  54.     //Derived class必須實作來自Base class的abstract method
  55.     //否則在程式中class無法被implementation
  56.     void printall(){
  57.         cout<<"hello world"<<endl;
  58.     }
  59.  
  60. protected:
  61.     int derived_id;
  62. };
  63. ////////////////////////////////////////////////////
  64. int main()
  65. {
  66.     Base *ptr = new Derived(1, "derived", 2);
  67.  
  68.     ptr->print();    //call Derived print()
  69.     ptr->printall();
  70.     delete ptr;
  71.  
  72.     return EXIT_SUCCESS;
  73. }

result

  • 在建構Derived class時,會先呼叫Base class的constructor,再呼叫Derived class的constructor,而destroy object時是相反的方向。
  • 當Base class的method全部為abstract method時,可將Base class視為Java的interface來使用。