# 學習 c++ 物件導向 :100: --- ###### tags: `c++`,`物件導向`,`指標`,`static`,`class` > [time=Wed, Jul 21, 2021 2:31 PM] > [TOC] > :::info > 歡迎觀賞!! > ::: --- ### classes(類別) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 cat 的類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: set_pos 設定位置 get_count 回傳數量 ----------------- */ class cat{ public: void set_pos(int,int); int get_count(); private: int count = 1; int posx,posy; }; void cat::set_pos(int x,int y){ posx = x; posy = y; } int cat::get_count(){ return count; } int main () { cat c1; c1.set_pos(1,2); std::cout << c1.get_count() << std::endl; } ``` 練習使用==classes==,並且了解到==public==和==private==的使用方式,以及成員函式的宣告,可以先宣告原型再利用外部宣告。 --- ### constructors & destructors(建構子&解構子) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 cat 的類別 ----------------- 變數: *count 數量的指標 *posx 紀錄x位置的指標 *posy 紀錄y位置的指標 ----------------- 函數: cat 設定初始值的建構子 get_count 回傳指標的數量 ~cat 刪除資料的解構子 ----------------- */ class cat{ public: cat(int,int,int); int get_count(); ~cat(); private: int *count; int *posx,*posy; }; cat::cat(int x,int y,int cnt){ posx = new int; posy = new int; count = new int; *posx = x; *posy = y; *count = cnt; } cat::~cat(){ delete posx; delete posy; delete count; } int cat::get_count(){ return *count; } int main () { cat c1 (1,2,5); std::cout << c1.get_count() << std::endl; } ``` 練習使用==constructors & destructors==,了解==建構子==和==解構子==的用途,以及使用方法。 !!==解構子==最常使用的地方在於動態管理的記憶體釋放。 --- ### Overloading Constructors(重載建構子) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 cat 的類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: get_count 回傳數量 ----------------- */ class cat{ public: int get_count(); int count,posx,posy; }; int cat::get_count(){ return count; } int main () { cat c1 ({5,2,5}); // [or] cat c1 std::cout << c1.get_count() << std::endl; } ``` 預設的建構子為 cat(),有兩種,第一種是無初始化空的建構子,第二種是可以初始化的建構子 ==empty constructor== ```cpp= cat(){} ``` ==copy constructor== ```cpp= cat(const &cat rv){ count = rv.count; posx = rv.posx; posy = rv.posy; } ``` ==多載函式== cat() cat(int,int) 可以寫成兩種同樣名稱的函式。 !!取代了預設的函式,所以原本的預設函式已經不存在了 ```cpp= #include <iostream> /* 宣告一個名稱為 cat 的類別 ----------------- 變數: *count 數量的指標 *posx 紀錄x位置的指標 *posy 紀錄y位置的指標 ----------------- 函數: cat 設定初始值的建構子 get_count 回傳指標的數量 ~cat 刪除資料的解構子 ----------------- */ class cat{ public: cat(); cat(int,int,int); int get_count(); int count,posx,posy; }; cat::cat(){ count = 1; posx = 1; posx = 1; } cat::cat(int cnt,int x,int y){ count = cnt; posx = x; posy = y; } int cat::get_count(){ return count; } int main () { cat c1 (1,2,3); cat c2; std::cout << c1.get_count() << std::endl; } ``` --- ### Pointers to Classes(類別指標) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 cat 的類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: set_value 設定數值 get_count 回傳數量 ----------------- */ class cat{ public: int set_value(int, int, int); int get_count(); int count,posx,posy; }; int cat::set_value(int a, int b, int c){ count = a; posx = b; posy = c; } int cat::get_count(){ return count; } int main () { cat c1; cat *c2; cat *c3; cat *c4; c2 = new cat; c3 = new cat[2]; c4 = &c1; c1.set_value(1,1,2); c2->set_value(2,3,4); c3->set_value(3,4,5); c3[1].set_value(3,5,6); std::cout << "c1 " << c1.get_count() << std::endl; std::cout << "c2 " << c2->get_count() << std::endl; std::cout << "c3[0] " << c3->get_count() << std::endl; std::cout << "c3[1] " << c3[1].get_count() << std::endl; std::cout << "c4 " << c4->get_count() << std::endl; } ``` 練習使用指向==class的指標==,以及==pointer==的使用方式。 --- ### Overloading Operators(重載運算子) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 cat 的類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: set_value 設定數值 get_count 回傳數量 operator+ 重載運算值 ----------------- */ class cat{ public: int count,posx,posy; void set_value(int, int, int); int get_count(); cat operator +(cat); }; void cat::set_value(int a, int b, int c){ count = a; posx = b; posy = c; } int cat::get_count(){ return count; } cat cat::operator+(cat c){ cat temp; temp.count = count + c.count; temp.posx = posx + c.posx; temp.posy = posy + c.posy; return temp; } int main () { cat c1,c2,c3; c1.set_value(1,1,2); c2.set_value(2,3,4); c3 = c1 + c2; std::cout << "c3 " << c3.get_count() << " " << c3.posx << " " << c3.posy << std::endl; } ``` --- ### This(this指標) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 cat 的類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: set_value 設定數值 get_count 回傳數量 isitme 檢查是否為正確的物件 operator+ 重載運算值 ----------------- */ class cat{ public: int count,posx,posy; void set_value(int, int, int); int get_count(); bool isitme(cat& param); cat operator +(cat); }; void cat::set_value(int a, int b, int c){ count = a; posx = b; posy = c; } int cat::get_count(){ return count; } bool cat::isitme(cat& param){ if(&param == this) return 1; else return 0; } cat cat::operator+(cat c){ count = count + c.count; posx = posx + c.posx; posy = posy + c.posy; return *this; } int main () { cat c1,c2,c3; c1.set_value(1,1,2); c2.set_value(2,3,4); c3 = c1 + c2; cat* c4; c4 = &c3; if(c4->isitme(c3)) std::cout << "c3 " << c4->get_count() << " " << c4->posx << " " << c4->posy << std::endl; } ``` --- ### Static Members(靜態成員) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 cat 的類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: set_value 設定數值 get_count 回傳數量 get_allcnt 回傳總數量 isitme 檢查是否為正確的物件 operator+ 重載運算值 ----------------- */ class cat{ public: int count,posx,posy; void set_value(int, int, int); int get_count(); static int get_allcnt(); bool isitme(cat& param); cat operator +(cat); private: static int cnt; }; void cat::set_value(int a, int b, int c){ count = a; cnt += count; posx = b; posy = c; } int cat::get_count(){ return count; } int cat::get_allcnt(){ return cnt; } bool cat::isitme(cat& param){ if(&param == this) return 1; else return 0; } cat cat::operator+(cat c){ count = count + c.count; posx = posx + c.posx; posy = posy + c.posy; return *this; } int cat::cnt = 0; int main () { cat c1,c2,c3; c1.set_value(1,1,2); c2.set_value(2,3,4); c3 = c1 + c2; cat* c4; c4 = &c3; if(c4->isitme(c3)) std::cout << "c3 " << c4->get_count() << " " << c4->posx << " " << c4->posy << std::endl; std::cout << "all:" << cat::get_allcnt() << std::endl; } ``` --- ### Friend(朋友函式) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 cat 的類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: set_value 設定數值 get_count 回傳數量 get_x 回傳x座標 get_y 回傳y座標 get_allcnt 回傳總數量 isitme 檢查是否為正確的物件 operator+ 重載運算值 ----------------- 宣告一個名稱為 fatcat 的類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: set_value 設定數值 get_allcnt 回傳總數量 ----------------- */ class fatcat; class cat{ public: void set_value(int, int, int); int get_count(); int get_x(); int get_y(); static int get_allcnt(); bool isitme(cat& param); cat operator +(cat); friend class fatcat; private: int count,posx,posy; static int cnt; }; class fatcat{ private: int count,posx,posy; static int cnt; public: static int get_allcnt(); void set_value(cat& rv); }; void cat::set_value(int a, int b, int c){ count = a; cnt += count; posx = b; posy = c; } void fatcat::set_value(cat& rv){ count = rv.count; cnt += rv.count; posx = rv.posx; posy = rv.posy; } int cat::get_count(){ return count; } int cat::get_x(){ return posx; } int cat::get_y(){ return posy; } int cat::get_allcnt(){ return cnt; } int fatcat::get_allcnt(){ return cnt; } bool cat::isitme(cat& param){ if(&param == this) return 1; else return 0; } cat cat::operator+(cat c){ count = count + c.count; posx = posx + c.posx; posy = posy + c.posy; return *this; } int cat::cnt = 0; int fatcat::cnt = 0; int main () { cat c1,c2,c3; c1.set_value(1,1,2); c2.set_value(2,3,4); c3 = c1 + c2; cat* c4; c4 = &c3; if(c4->isitme(c3)) std::cout << "c3 " << c4->get_count() << " " << c4->get_x() << " " << c4->get_y() << std::endl; std::cout << "all:" << cat::get_allcnt() << std::endl; fatcat fc1; fc1.set_value(c3); std::cout << fc1.get_allcnt() << std::endl; } ``` --- ### Inheritance(繼承) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 allcat 的父類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: ----------------- 宣告一個名稱為 cat 的子類別 ----------------- 變數: ----------------- 函數: set_value 設定數值 get_count 回傳數量 get_x 回傳x座標 get_y 回傳y座標 get_allcnt 回傳總數量 isitme 檢查是否為正確的物件 operator+ 重載運算值 ----------------- 宣告一個名稱為 fatcat 的子類別 ----------------- 變數: ----------------- 函數: set_value 設定數值 get_allcnt 回傳總數量 ----------------- */ class allcat{ protected: int count,posx,posy; static int cnt; }; class fatcat; class cat : private allcat{ public: void set_value(int, int, int); int get_count(); int get_x(); int get_y(); static int get_allcnt(); bool isitme(cat& param); cat operator +(cat); friend class fatcat; }; class fatcat : private allcat{ public: static int get_allcnt(); void set_value(cat& rv); }; void cat::set_value(int a, int b, int c){ count = a; cnt += count; posx = b; posy = c; } void fatcat::set_value(cat& rv){ count = rv.count; cnt += rv.count; posx = rv.posx; posy = rv.posy; } int cat::get_count(){ return count; } int cat::get_x(){ return posx; } int cat::get_y(){ return posy; } int cat::get_allcnt(){ return cnt; } int fatcat::get_allcnt(){ return cnt; } bool cat::isitme(cat& param){ if(&param == this) return 1; else return 0; } cat cat::operator+(cat c){ count = count + c.count; posx = posx + c.posx; posy = posy + c.posy; return *this; } int allcat::cnt = 0; int main () { cat c1,c2,c3; c1.set_value(1,1,2); c2.set_value(2,3,4); c3 = c1 + c2; cat* c4; c4 = &c3; if(c4->isitme(c3)) std::cout << "c3 " << c4->get_count() << " " << c4->get_x() << " " << c4->get_y() << std::endl; std::cout << "all:" << cat::get_allcnt() << std::endl; fatcat fc1; fc1.set_value(c3); std::cout << fc1.get_allcnt() << std::endl; } ``` --- ### Pointers to Base Class(父類別指標) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 allcat 的父類別 ----------------- 變數: count 數量 get_allcnt 回傳總數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: ----------------- 宣告一個名稱為 cat 的子類別 ----------------- 變數: ----------------- 函數: set_value 設定數值 get_count 回傳數量 get_x 回傳x座標 get_y 回傳y座標 isitme 檢查是否為正確的物件 operator+ 重載運算值 ----------------- 宣告一個名稱為 fatcat 的子類別 ----------------- 變數: ----------------- 函數: set_value 設定數值 ----------------- */ class allcat{ public: int count,posx,posy; static int cnt; static int get_allcnt(); }; class fatcat; class cat : public allcat{ public: void set_value(int, int, int); int get_count(); int get_x(); int get_y(); bool isitme(cat& param); cat operator +(cat); friend class fatcat; }; class fatcat : public allcat{ public: void set_value(cat& rv); }; void cat::set_value(int a, int b, int c){ count = a; cnt += count; posx = b; posy = c; } void fatcat::set_value(cat& rv){ count = rv.count; cnt += rv.count; posx = rv.posx; posy = rv.posy; } int cat::get_count(){ return count; } int cat::get_x(){ return posx; } int cat::get_y(){ return posy; } int allcat::get_allcnt(){ return cnt; } bool cat::isitme(cat& param){ if(&param == this) return 1; else return 0; } cat cat::operator+(cat c){ count = count + c.count; posx = posx + c.posx; posy = posy + c.posy; return *this; } int allcat::cnt = 0; int main () { cat c1,c2,c3; c1.set_value(1,1,2); c2.set_value(2,3,4); c3 = c1 + c2; cat* c4; c4 = &c3; allcat* c5 = &c1; allcat* c6 = &c2; if(c4->isitme(c3)) std::cout << "c3 " << c4->get_count() << " " << c4->get_x() << " " << c4->get_y() << std::endl; std::cout << "all:" << c5->get_allcnt() << std::endl; fatcat fc1; fc1.set_value(c3); std::cout << c6->get_allcnt() << std::endl; } ``` --- ### Polymorphism:Virtual Members(虛擬成員) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 allcat 的父類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: get_allcnt 回傳總數量 get_count 回傳數量(虛擬) ----------------- 宣告一個名稱為 cat 的子類別 ----------------- 變數: ----------------- 函數: set_value 設定數值 get_count 回傳數量 get_x 回傳x座標 get_y 回傳y座標 isitme 檢查是否為正確的物件 operator+ 重載運算值 ----------------- 宣告一個名稱為 fatcat 的子類別 ----------------- 變數: ----------------- 函數: set_value 設定數值 get_count 回傳數量 ----------------- */ class allcat{ public: int count,posx,posy; static int cnt; static int get_allcnt(); virtual int get_count(void){ return 0; } }; class fatcat; class cat : public allcat{ public: void set_value(int, int, int); int get_count(); int get_x(); int get_y(); bool isitme(cat& param); cat operator +(cat); friend class fatcat; }; class fatcat : public allcat{ public: void set_value(cat& rv); int get_count(); }; void cat::set_value(int a, int b, int c){ count = a; cnt += count; posx = b; posy = c; } void fatcat::set_value(cat& rv){ count = rv.count; cnt += rv.count; posx = rv.posx; posy = rv.posy; } int cat::get_count(){ return count; } int fatcat::get_count(){ return count; } int cat::get_x(){ return posx; } int cat::get_y(){ return posy; } int allcat::get_allcnt(){ return cnt; } bool cat::isitme(cat& param){ if(&param == this) return 1; else return 0; } cat cat::operator+(cat c){ count = count + c.count; posx = posx + c.posx; posy = posy + c.posy; return *this; } int allcat::cnt = 0; int main () { cat c1,c2,c3; c1.set_value(1,1,2); c2.set_value(2,3,4); c3 = c1 + c2; cat* c4; c4 = &c3; allcat* c5 = &c1; if(c4->isitme(c3)) std::cout << "c3 " << c4->get_count() << " " << c4->get_x() << " " << c4->get_y() << std::endl; std::cout << "all:" << c5->get_allcnt() << std::endl; fatcat fc1; fc1.set_value(c3); allcat* c6 = &fc1; std::cout << c6->get_allcnt() << std::endl; std::cout << c5->get_count() << std::endl; std::cout << c6->get_count() << std::endl; } ``` --- ### Polymorphism:Abstract Base Classes(抽象類別) :smile_cat: ```cpp= #include <iostream> /* 宣告一個名稱為 allcat 的父類別 ----------------- 變數: count 數量 posx 紀錄x位置 posy 紀錄y位置 ----------------- 函數: get_allcnt 回傳總數量 get_count 回傳數量(虛擬) ----------------- 宣告一個名稱為 cat 的子類別 ----------------- 變數: ----------------- 函數: set_value 設定數值 get_count 回傳數量 get_x 回傳x座標 get_y 回傳y座標 isitme 檢查是否為正確的物件 operator+ 重載運算值 ----------------- 宣告一個名稱為 fatcat 的子類別 ----------------- 變數: ----------------- 函數: set_value 設定數值 get_count 回傳數量 ----------------- */ class allcat{ public: int count,posx,posy; static int cnt; static int get_allcnt(); virtual int get_count(void)=0; void printcount(void){ std::cout << this->get_count() << std::endl; } }; class fatcat; class cat : public allcat{ public: void set_value(int, int, int); int get_count(); int get_x(); int get_y(); bool isitme(cat& param); cat operator +(cat); friend class fatcat; }; class fatcat : public allcat{ public: void set_value(cat& rv); int get_count(); }; void cat::set_value(int a, int b, int c){ count = a; cnt += count; posx = b; posy = c; } void fatcat::set_value(cat& rv){ count = rv.count; cnt += rv.count; posx = rv.posx; posy = rv.posy; } int cat::get_count(){ return count; } int fatcat::get_count(){ return count; } int cat::get_x(){ return posx; } int cat::get_y(){ return posy; } int allcat::get_allcnt(){ return cnt; } bool cat::isitme(cat& param){ if(&param == this) return 1; else return 0; } cat cat::operator+(cat c){ count = count + c.count; posx = posx + c.posx; posy = posy + c.posy; return *this; } int allcat::cnt = 0; int main () { cat c1,c2,c3; c1.set_value(1,1,2); c2.set_value(2,3,4); c3 = c1 + c2; cat* c4; c4 = &c3; allcat* c5 = &c1; if(c4->isitme(c3)) std::cout << "c3 " << c4->get_count() << " " << c4->get_x() << " " << c4->get_y() << std::endl; std::cout << "all:" << c5->get_allcnt() << std::endl; fatcat fc1; fc1.set_value(c3); allcat* c6 = &fc1; std::cout << c6->get_allcnt() << std::endl; c5->printcount(); c6->printcount(); } ``` ---