《21天C++》筆記之6月27日
阿新 • • 發佈:2017-06-27
另一個 聲明 fast 自由 不支持 stream mem strings 析構函數
繼承
- 公有繼承,is-a的關系,比如,He is a man;
派生類可訪問基類非私有成員,派生類實例也是;
- 私有繼承和保護繼承,has-a的關系,Car has a motor;
私有繼承,也讓派生類可訪問基類非私有成員,但派生類實例無法訪問基類任何成員,並且派生類的的子類也無法訪問基類任何成員;
保護繼承,與私有繼承不同的是,子類的子類是可以訪問基類的非私有成員;
註意:僅當必要時才使用私有或保護繼承,遇到has-a情況時,盡量用組合或者聚合的方式替代(即將‘基類對象當作‘子類’‘的一個成員屬性)
class Motor { public: void SwitchIgnition(); void PumpFuel(); void FireCylinders(); }; class Car { private: Motor heartOfCar; public: void Move() { heartOfCar.FireCylinders(); heartOfCar.PumpFuel(); heartOfCar.SwitchIgnition(); } };
- 切除:將子類對象顯示復制給父類對象,或通過參數傳遞給父類對象,會只保留Base部分,這叫做切除
class Platypus:public Mammal,public Reptile,public Bird{};//多繼承
- 重載,覆蓋,隱藏:重載就是一個類裏同名不同參數的函數,覆蓋就是子類與父類同名同參數的函數,隱藏就是子類會將父類中同名但不同參數的函數隱藏,即實例不能訪問。
多態
- 使用虛函數實現多態行為,通過引用或者指針調用虛函數即可實現多態
將派生類對象視為基類對象,並執行派生類的覆蓋函數
class Fish { public: virtual void Swim() { cout<< "Fish Swim.." << endl; } }; class Tuna : public Fish { public: virtual void Swim() { cout << "Tuna is fast" << endl; } }; class Carp : public Fish { public: virtual void Swim() { cout << "Carp is slow" << endl; } };int main() { Tuna t; Carp c; Fish &f1 = t; f1.Swim(); return 0; }
- 對於使用new在自由存儲區中實例化派生類對象,如果將其付給基類指針,
- 並通過該指針調用delete,將不會調用派生類的析構函數.
- 這可能會導致資源未釋放,內存泄露等問題.
- 要避免這種問題,要將析構函數聲明為虛函數.
class Fish { public: Fish() { cout <<"Constructed Fish"<< endl; } ~Fish() { cout << "Destroyed Fish" << endl; } }; class Tuna : public Fish { public: Tuna() { cout << "Constructed Tuna" <<endl; } ~Tuna() { cout << "Destroyed Tuna" << endl; } }; void DeleteFishMemory(Fish *pFish) { delete pFish; } int main() { Tuna *pTuna = new Tuna; DeleteFishMemory(pTuna); return 0; } /*輸出: **Constructed Fish **Constructed Tuna **Destroyed Fish */
抽象基類與純虛函數
不能被實例化的基類稱為抽象基類,可通過聲明純虛函數創建.
class Fish { public: virtual void Swim() = 0; }; class Tuna : public Fish { public: void Swim() { cout << "Tuna swims fast in the sea " << endl; } };
使用虛繼承解決菱形問題,(二義性)
class Animal { public: Animal() { cout << "ANimal constructor" << endl; } int Age; }; class Mammal:public virtual Animal { }; class Bird:public virtual Animal {}; class Reptile:public virtual Animal {}; class Platypus:public Mammal, public Bird, public Reptile { public: Platypus() { cout << "Platypus constructor" <<endl; } }; int main() { Platypus duckBilledp; duckBilledp.Age = 25; return 0; }
- 繼承多個從同一個類派生而來的基類時,如果沒有使用虛繼承,將會繼承多個基類的父類,而使用了虛繼承,則只繼承一個.
- virtual關鍵字有兩個不同概念,一個是用於多態,另一個是用於虛繼承解決二義性
從技術上說,C++不支持虛復制構造函數
運算符類型與運算符重載
- 單目運算符
1, (++)遞增運算符
Date operator ++ (){} 單目前綴運算符在類中重載
Date operator ++ (int){}單目後綴運算符在類中重載
2, 轉換運算符,下例是用轉換運算符將Date轉換為const char*
class Date { private: int Day; int Month; int Year; string DateInString; public: Date (int InputDay, int InputMonth, int InputYear) : Day(InputDay), Month(InputMonth), Year(InputYear) {} operator const char*() { ostringstream formattedDate; formattedDate << Day << " / " << Month << " / " << Year; DateInString = formattedDate.str(); return DateInString.c_str(); } }; int main() { Date Holiday (25, 12, 2011); cout << "Holiday is on: " << Holiday << endl; return 0; } //結果:Holiday is on: 25 / 12 / 2011
《21天C++》筆記之6月27日