閑雲潭影日悠悠,物換星移幾度秋
你既然已經做出了選擇, 又何必去問為什么選擇。鬼谷絕學的要義, 從來都不是回答, 而是抉與擇
普通類

#ifndef TABTENN0_H_ #define TABTENN0_H_ #include <string> using namespace std; class TableTennisPlayer { private: string firstname; string lastname; bool hasTable; public: TableTennisPlayer ( const string & fn = "none", const string & ln = "none", bool ht = false ); void Name() const; bool HasTable() const {return hasTable;}; void ResetTable(bool v) {hasTable = v;}; }; #endif

#include <iostream> #include <string> #include "tabtenn0.h" using namespace std; TableTennisPlayer::TableTennisPlayer(const string & fn, const string & ln, bool ht): firstname(fn), lastname(ln), hasTable(ht) {} void TableTennisPlayer::Name () const { std::cout << lastname << "," << firstname ; }

#include <iostream> #include "tabtenn0.h" using namespace std; int main (int argc, char const *argv[]) { TableTennisPlayer player1("Chuck", "Blizzard", true); TableTennisPlayer player2("Tara", "Boomdea", false); player1.Name(); if (player1.HasTable()){ std::cout << ":has a table." << '\n'; }else{ std::cout << ":hasn't a table." << '\n'; }; player2.Name(); if (player2.HasTable()){ std::cout << ":has a table" << '\n'; }else{ std::cout << ":hasn't a table." << '\n'; }; return 0; }
繼承類
基類的private成員都不能被派生類訪問。
聲明為public的方法和屬性可以被隨意訪問;
聲明為protected的方法和屬性只能被類本身和其子類訪問;
而聲明為private的方法和屬性只能被當前類的對象訪問。

#include <iostream> #include <string> using namespace std; class Father { private: string first_name; string last_name; public: Father(string fn, string ln): first_name(fn), last_name(ln) {}; void Name() {std::cout << first_name << ","<< last_name << '\n';}; }; class Son: public Father // 這句很重要呀 { private: public: Son(string an, string bn):Father(an, bn){}; }; int main(int argc, char const *argv[]) { // Father father("張三", "李四"); // father.Name(); Son son("張三", "李四"); son.Name(); return 0; }
下面這個是兩種展示調用基類方法的方式很有意思, 設計到拷貝構造和深淺拷貝, 有興趣可以百度下

#ifndef TABTENN1_H_ #define TABTENN1_H_ #include <string> using namespace std; class TableTennisPlayer { private: string firstname; string lastname; bool hasTable; public: TableTennisPlayer(const string & fn = "none", const string & ln = "none", bool ht = false); void Name() const; bool HasTable() const {return hasTable;}; void ResetTable(bool v) {hasTable = v;}; }; class RatedPlayer: public TableTennisPlayer { private: unsigned int rating; public: RatedPlayer (unsigned int r = 0, const string & fn = "none", const string & ln = "none", bool ht = false ); RatedPlayer (unsigned int r, const TableTennisPlayer & tp); unsigned int Rating() const {return rating;}; void ResetRating (unsigned int r) {rating = r;}; }; #endif

#include <iostream> #include "tabtenn1.h" TableTennisPlayer::TableTennisPlayer ( const string & fn, const string & ln, bool ht):firstname(fn), lastname(ln), hasTable(ht) {} void TableTennisPlayer::Name() const { std::cout << lastname << ", " << firstname ; } RatedPlayer::RatedPlayer ( unsigned int r, const string & fn, const string & ln, bool ht): TableTennisPlayer(fn, ln, ht){ rating = r; } RatedPlayer::RatedPlayer( unsigned int r, const TableTennisPlayer & tp ):TableTennisPlayer(tp), rating(r) {} /* 問題是上面這個類方法函數: RatedPlayer::RatedPlayer( unsigned int r, const TableTennisPlayer & tp ):TableTennisPlayer(tp), rating(r) {} 的TableTennisPlayer(tp) 是不是等於 TableTennisPlayer = tp的意思 但是usett1.cpp 里面傳入以后player1的作用是什么? */

#include <iostream> #include <string> #include "tabtenn1.h" using namespace std; int main(int argc, char const *argv[]) { /* TableTennisPlayer player1("Tara", "Boomdea", false); RatedPlayer rplayer1(1140, "Mallory", "Duck", true); rplayer1.Name(); if (rplayer1.HasTable()) { std::cout << ": has a table." << '\n'; }else { std::cout << ": hasn't a table." << '\n'; } std::cout << "Name:"; rplayer1.Name(); std::cout << "; Rating : " << rplayer1.Rating() << '\n'; */ TableTennisPlayer player1("Tara", "Boomdea", false); RatedPlayer rplayer2 (1212, player1); std::cout << "Name: "; rplayer2.Name(); std::cout << "; Rating : " << rplayer2.Rating() << '\n'; return 0; }
分為三種:
{
公有繼承,
保護繼承,
私有繼承
}
從一個類派生出另一個類時, 原始類成為基類, 繼承類成為派生類。粗俗的講:子繼承父, 父就是基類, 子就是派生類
這說明繼承, 首先需要一個基類。
對於公有派生, 派生類對象包含基類對象, 基類的公有成員將成為派生類的公有成員;
基類的私有部分也將成為派生類的一部分, 但只能通過基類的公有和保護方法訪問。換句話說: "派生類不能訪問基類的私有成員, 必須通過基類的方法進行"
簡單寫法
class RatedPlayer: public TableTennisPlayer { private: public: };
構造函數
RatedPlayer::RatedPlayer( unsigned int r, const string & fn, const string & fn, cosnt string & ln, bool ht ): TableTennisPlayer(fn, ln, ht) // 初始化基類構造函數, 或者說成員初始化列表 { rating = r; }
// 如果賦值RatedPlayer rplayer(1140, "Mallory", "Duck", true),
// 同時將“Mallory”, "Duck" 和 true賦給fn、ln和ht作為實參傳遞給TableTennisPlayer構造函數
如果省略成員初始化列表, 將會怎么樣?
RatedPlayer::RatedPlayer( unsigned int r, const string & fn, const string & fn, cosnt string & ln, bool ht ) { rating = r; } 如果不調用基類構造函數, 與下面代碼等效, 程序將使用默認的基類構造函數 RatedPlayer::RatedPlayer( unsigned int r, const string & fn, const string & fn, cosnt string & ln, bool ht ): TableTennisPlayer() // 程序將使用默認的基類構造函數, 上面代碼與此等效 { rating = r; }
注意: 除非要使用默認構造函數, 否則應顯式調用正確的基類構造函數。
RatedPlayer::RatedPlayer( unsigned int r, const string & fn, const string & fn, cosnt string & ln, bool ht ): TableTennisPlayer(tp) { rating = r; }
未完待續...