繼承:在定義一個新的類B時,若是該類與某個已有的類A類似(B擁有A的所有特色),那麼就能夠把A做爲一個基類,而把B做爲基類的一個派生類(子類)ios
派生類是經過對基類進行修改和擴充獲得的,在派生類中,能夠擴充新的成員變量和成員函數數組
派生類一經定義後,能夠獨立使用,不依賴於基類函數
派生類擁有基類的所有成員函數和成員變量,不管是private、protected、public.學習
class 派生類名: public 基類名 { };
class CStudent{ private: string sName; int nAge; public: bool IsThreeGood(){}; void SrtName(const string & name) {sName = name;} //...... }; class CUndergraduateStudent: public CStudent{ private: int nDepartment; public: bool IsThreeGood(){...};//覆蓋 bool CanBaoYan(){...}; }; class CGraduatedStudent:public CStudent{ private: int nDepartment; char szMentorName[20]; public: int CountSalary(){...}; };
派生類對象的體積,等於基類對象的體積+派生類對象本身的成員變量的體積。在派生類對象中,包含着基類對象。並且基類對象的存儲位置位於派生類對象新增的成員變量以前。ui
class CPoint { double x,y; friend class CCircle;//便於Ccircle類操做其圓心 }; class CCircle { double r; CPoint center; };
class base{ int j; public: int i; void func(); } class derived: public base{ public: int i; void access(); void func(); } void derived::access() { j = 5;//error,j是基類的私有成員變量 i = 5;//引用的是派生類的i base::i = 5;//引用的是基類的i func(); //派生類的 base::func();//基類的 } derived obj; obj.i = 1;//派生類賦值 obj.base::i = 1;//基類賦值
基類的private成員:能夠被下列函數訪問this
基類的public成員:能夠被下列函數訪問spa
基類的protected成員:能夠被下列函數訪問3d
class Father{ private: int nPrivate; public: int nPublic; protected: int nProtected; }; class Son: public Father{ void AccessFather(){ nPublic = 1; //ok nPrivate = 1;//wrong nProtected = 1;//OK,訪問當前對象從基類繼承的protected成員 Son f; f.nProtected = 1;//wrong,f不是當前對象 } };
派生類對象包含基類對象指針
執行派生類構造函數以前,先執行基類的構造函數code
派生類交代基類初始化,具體形式:
構造函數名(形參表):基類名(基類構造函數實參表)
class Bug{ private: int nLegs; int nColor; public: int nType; Bug(int legs, int color); void PrintBug(){ }; }; class FlyBug:public Bug{ int nWings; public: FlyBug(int legs, int color, int wings); }; Bug::Bug(int legs, int color){ nLegs = legs; nColor = color; } FlayBug::FlyBug(int legs, int color, int wings):Bug(legs,color){ nWings = wings; }
在建立派生類的對象時
調用基類構造函數的兩種方式
派生類的析構函數被執行時,執行完派生類的析構函數後,自動調用基類的析構函數
class Skill{ public: skill(int n){ } }; class FlyBug: public Bug{ int nWings; Skill sk1,sk2; public: FlyBug(int legs,int color,int wings); }; FlyBug::FlyBug(int legs, int color, int wings):Bug(legs,color),sk1(5),sk2(color){ nWings = wings; }
class base{}; class derived: public base{ }; base b; derived d;
注:填空題在Coursera提交時,文件中只需出現填進去的內容便可
#include <iostream> #include <cstring> #include <cstdlib> using namespace std; class MyString: public string { public: MyString(string string1):string(string1){}; MyString():string(){}; MyString(const char* a):string(a){}; string operator()(int a,int b){ return substr(a,b); } }; int CompareString( const void * e1, const void * e2) { MyString * s1 = (MyString * ) e1; MyString * s2 = (MyString * ) e2; if( *s1 < *s2 ) return -1; else if( *s1 == *s2 ) return 0; else if( *s1 > *s2 ) return 1; } int main() { MyString s1("abcd-"),s2,s3("efgh-"),s4(s1); MyString SArray[4] = {"big","me","about","take"}; cout << "1. " << s1 << s2 << s3<< s4<< endl; s4 = s3; s3 = s1 + s3; cout << "2. " << s1 << endl; cout << "3. " << s2 << endl; cout << "4. " << s3 << endl; cout << "5. " << s4 << endl; cout << "6. " << s1[2] << endl; s2 = s1; s1 = "ijkl-"; s1[2] = 'A' ; cout << "7. " << s2 << endl; cout << "8. " << s1 << endl; s1 += "mnop"; cout << "9. " << s1 << endl; s4 = "qrst-" + s2; cout << "10. " << s4 << endl; s1 = s2 + s4 + " uvw " + "xyz"; cout << "11. " << s1 << endl; qsort(SArray,4,sizeof(MyString), CompareString); for( int i = 0;i < 4;++i ) cout << SArray[i] << endl; //輸出s1從下標0開始長度爲4的子串 cout << s1(0,4) << endl; //輸出s1從下標爲5開始長度爲10的子串 cout << s1(5,10) << endl; return 0; }
#include <iostream> #include <cstdio> #include <string> using namespace std; const int WARRIOR_NUM = 5; const int WEAPONS_NUM = 3; /* string Warrior::names[WARRIOR_NUM] = { "dragon","ninja","iceman","lion","wolf" }; 紅方司令部按照 iceman、lion、wolf、ninja、dragon 的順序製造武士。 藍方司令部按照 lion、dragon、ninja、iceman、wolf 的順序製造武士。 */ class Headquarter; class Warrior { private: Headquarter * pHeadquarter; //指向英雄所屬陣營的指針 int kindNo;//武士的種類編號 0 dragon 1 ninja 2 iceman 3 lion 4 wolf int no;//英雄編號 public: static string weapons[WEAPONS_NUM];//存放3種武器名字的數組 static string names[WARRIOR_NUM]; //存放5種職業名字的數組 static int initialLifeValue [WARRIOR_NUM]; //存放不一樣英雄的起始生命值(從輸入中採集) Warrior( Headquarter *p,int no_,int kindNo_);//構造函數 void PrintResult(int nTime); //執行打印數據的工做,若沒法繼續建立則輸出結束並中止 }; class dragon: public Warrior { private: int weaponNum1;//dragon有1件武器,武器編號 0 sword 1 bomb 2 arrow double morale;//dragon的士氣值 public: dragon(Headquarter *p,int no_,int kindNo_); void PrintResult(int nTime); }; class ninja: public Warrior { private: int weaponNum1,weaponNum2;//ninja有2件武器,武器編號 0 sword 1 bomb 2 arrow public: ninja(Headquarter *p,int no_,int kindNo_); void PrintResult(int nTime); }; class iceman: public Warrior { private: int weaponNum1;//iceman有1件武器,武器編號 0 sword 1 bomb 2 arrow public: iceman(Headquarter *p,int no_,int kindNo_); void PrintResult(int nTime); }; class lion: public Warrior { private: int loyalty;//lion的忠誠度 public: lion(Headquarter *p,int no_,int kindNo_); void PrintResult(int nTime); }; //wolf由於沒有特色,故不須要專門的類 class Headquarter { private: int totalLifeValue; bool stopped; int totalWarriorNum; int color; int curMakingSeqIdx; //當前要製造的武士是製造序列中的第幾個 int warriorNum[WARRIOR_NUM]; //存放每種武士的數量 Warrior * pWarriors[1000];//和每一個建立的英雄創建連接 public: friend class Warrior; friend class ninja; friend class lion; friend class dragon; friend class iceman; static int makingSeq[2][WARRIOR_NUM];//武士的製做序列,按陣營的不一樣分紅兩個 void Init(int color_, int lv); //初始化陣營須要顏色和總血量 ~Headquarter(); int Produce(int nTime); //建立英雄,輸入時間 string GetColor(); }; Warrior::Warrior(Headquarter *p, int no_, int kindNo_) { no = no_; kindNo = kindNo_; pHeadquarter = p; } void Warrior::PrintResult(int nTime) { string color = pHeadquarter->GetColor(); printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n", nTime, color.c_str(), names[kindNo].c_str(),no,initialLifeValue[kindNo], pHeadquarter->warriorNum[kindNo],names[kindNo].c_str(),color.c_str()); // string 在printf中輸出的函數調用c_str() } dragon::dragon(Headquarter *p, int no_, int kindNo_):Warrior(p,no_,kindNo_) { weaponNum1 = no_ % 3; morale = (double)p->totalLifeValue / (double)initialLifeValue[kindNo_]; } void dragon::PrintResult(int nTime) { Warrior::PrintResult(nTime); printf("It has a %s,and it's morale is %.2f\n", weapons[weaponNum1].c_str(),morale); } ninja::ninja(Headquarter *p, int no_, int kindNo_) :Warrior(p,no_,kindNo_){ weaponNum1 = no_ % 3; weaponNum2 = (no_+1) % 3; } void ninja::PrintResult(int nTime) { Warrior::PrintResult(nTime); printf("It has a %s and a %s\n", weapons[weaponNum1].c_str(),weapons[weaponNum2].c_str()); } iceman::iceman(Headquarter *p, int no_, int kindNo_) :Warrior(p,no_,kindNo_){ weaponNum1 = no_ % 3; } void iceman::PrintResult(int nTime) { Warrior::PrintResult(nTime); printf("It has a %s\n", weapons[weaponNum1].c_str()); } lion::lion(Headquarter *p, int no_, int kindNo_) :Warrior(p,no_,kindNo_){ loyalty = p->totalLifeValue; } void lion::PrintResult(int nTime) { Warrior::PrintResult(nTime); printf("It's loyalty is %d\n", loyalty); } void Headquarter::Init(int color_, int lv) { color = color_; totalLifeValue = lv; totalWarriorNum = 0; stopped = false; curMakingSeqIdx = 0; for (int i = 0; i < WARRIOR_NUM; i++) { warriorNum[i] = 0; } } Headquarter::~Headquarter() { for (int i = 0; i < totalWarriorNum; i++) { delete pWarriors[i]; } } int Headquarter::Produce(int nTime) { if(stopped) return 0; int searchingTimes = 0; while(Warrior::initialLifeValue[makingSeq[color][curMakingSeqIdx]] > totalLifeValue && searchingTimes < WARRIOR_NUM) { curMakingSeqIdx = (curMakingSeqIdx + 1) % WARRIOR_NUM; searchingTimes++; } int kindNo = makingSeq[color][curMakingSeqIdx]; if(Warrior::initialLifeValue[kindNo] > totalLifeValue) { stopped = true; if(color == 0) printf("%03d red headquarter stops making warriors\n",nTime); else printf("%03d blue headquarter stops making warriors\n",nTime); return 0; } //排除全部其餘條件後,開始製做士兵 totalLifeValue -= Warrior::initialLifeValue[kindNo]; curMakingSeqIdx =( curMakingSeqIdx + 1) % WARRIOR_NUM; if(kindNo == 0) { pWarriors[totalWarriorNum] = new dragon(this, totalWarriorNum + 1, kindNo); warriorNum[kindNo]++; dragon* p = (dragon *)pWarriors[totalWarriorNum]; p->PrintResult(nTime); totalWarriorNum++; return 1; } else if(kindNo == 1){ pWarriors[totalWarriorNum] = new ninja(this,totalWarriorNum+1,kindNo); warriorNum[kindNo]++; ninja* p = (ninja *)pWarriors[totalWarriorNum]; p->PrintResult(nTime); totalWarriorNum++; return 1; } else if(kindNo == 2){ pWarriors[totalWarriorNum] = new iceman(this,totalWarriorNum+1,kindNo); warriorNum[kindNo]++; iceman* p = (iceman *)pWarriors[totalWarriorNum]; p->PrintResult(nTime); totalWarriorNum++; return 1; } else if(kindNo == 3){ pWarriors[totalWarriorNum] = new lion(this,totalWarriorNum+1,kindNo); warriorNum[kindNo]++; lion* p = (lion *)pWarriors[totalWarriorNum]; p->PrintResult(nTime); totalWarriorNum++; return 1; } else if(kindNo == 4){ pWarriors[totalWarriorNum] = new Warrior(this,totalWarriorNum+1,kindNo); warriorNum[kindNo]++; pWarriors[totalWarriorNum]->PrintResult(nTime); totalWarriorNum++; return 1; } } string Headquarter::GetColor() { if(color == 0) return "red"; else return "blue"; } string Warrior::names[WARRIOR_NUM] = {"dragon","ninja","iceman","lion","wolf"}; string Warrior::weapons[WEAPONS_NUM] = {"sword","bomb","arrow"}; int Warrior::initialLifeValue[WARRIOR_NUM]; int Headquarter::makingSeq[2][WARRIOR_NUM]={{2,3,4,1,0},{3,0,1,2,4}};//兩個司令部武士的製做順序序列 int main() { int t; int m; Headquarter RedHead,BlueHead; scanf("%d", &t); //讀取case數 int nCaseNo = 1; while(t--){ printf("Case:%d\n",nCaseNo++); scanf("%d",&m);//讀取基地總血量 for (int i = 0; i < WARRIOR_NUM; i++) { scanf("%d",&Warrior::initialLifeValue[i]); } RedHead.Init(0,m); BlueHead.Init(1,m); int nTime = 0; while (true){ int tmp1 = RedHead.Produce(nTime); int tmp2 = BlueHead.Produce(nTime); if( tmp1 == 0 && tmp2 == 0) break; nTime++; } } return 0; } /* * 魔獸世界2就是在魔獸世界1的基礎上作一些改動 * 雖然輸出結果是正確的沒錯……可我總以爲Produce的函數被我寫的有點囉嗦Orz * 父類指針指向子類對象想調用子類函數還真是有點麻煩呢…… * 或許會有更好的方法?在之後的學習中試試看吧 * 搜索的時候發現了virtual之類的東西……後面應該會學到? */