C++(14)--面向对象
面向?qū)ο?/h3>- 1.面向?qū)ο缶幊?難點)
- 2.類和對象
- demo1:地主類的實現(xiàn)版本1
- demo2:地主類的實現(xiàn)版本2
- 3.訪問修飾符
- demo3:外部修改成員變量不安全(版本3)
- demo4: 使用封裝防止直接修改成員變量(版本3)
- demo5:進一步封裝:設(shè)置/獲取名字,修改積分(版本4)
- 4.構(gòu)造函數(shù)與析構(gòu)函數(shù)(重點)
- 4.1默認構(gòu)造函數(shù)
- demo6: 使用構(gòu)造函數(shù)進行成員變量的初始化
- 4.2 帶參構(gòu)造函數(shù)
- demo7:學(xué)生類構(gòu)建--堆內(nèi)存對象/棧內(nèi)存對象
- 4.3 析構(gòu)函數(shù)
- demo8:學(xué)生類析構(gòu)函數(shù)演示
- 5.this指針(重點)
- demo9:學(xué)霸返回引用的使用
《老九學(xué)堂C++課程》《C++ primer》學(xué)習(xí)筆記。《老九學(xué)堂C++課程》詳情請到B站搜索《老九零基礎(chǔ)學(xué)編程C++入門》
-------------簡單的事情重復(fù)做,重復(fù)的事情用心做,用心的事情堅持做(老九君)---------------
- demo1:地主類的實現(xiàn)版本1
- demo2:地主類的實現(xiàn)版本2
- demo3:外部修改成員變量不安全(版本3)
- demo4: 使用封裝防止直接修改成員變量(版本3)
- demo5:進一步封裝:設(shè)置/獲取名字,修改積分(版本4)
- 4.1默認構(gòu)造函數(shù)
- demo6: 使用構(gòu)造函數(shù)進行成員變量的初始化
- 4.2 帶參構(gòu)造函數(shù)
- demo7:學(xué)生類構(gòu)建--堆內(nèi)存對象/棧內(nèi)存對象
- 4.3 析構(gòu)函數(shù)
- demo8:學(xué)生類析構(gòu)函數(shù)演示
- demo9:學(xué)霸返回引用的使用
1.面向?qū)ο缶幊?難點)
oop: object oriented programming
何為面向?qū)ο?#xff1a;基于對象的概念,以對象為中心,以類和繼承為構(gòu)造機制,來認識、理解、刻畫客觀世界;涉及構(gòu)建相應(yīng)的軟件系統(tǒng)(模擬現(xiàn)實)
1.對象–有數(shù)據(jù)和容許的操作組成的封裝體,與客觀實體有直接的對應(yīng)關(guān)系(屬性和方法的集合)
面向?qū)ο蟛皇悄骋环N語言的特性,而是一種編程思想。原來面向過程代碼超過10W行就會難管理,原來有因為飛機控制程序中一個,寫成.號造成的空難。
舉個粒子:斗地主游戲的開發(fā)
面向過程:一步一步來,很多很多的過程函數(shù):開始游戲-洗牌-發(fā)牌-顯示手牌…-輸出結(jié)果
面向?qū)ο?#xff1a;
1.游戲參與者,行為模式是相同的–玩家對象,相同的屬性和行為;
2.進行游戲的場景–牌桌對象,負責現(xiàn)實游戲的界面及內(nèi)容;
3.游戲規(guī)則系統(tǒng)–裁判對象,負責判定牌面、輸贏;
小結(jié):
1.面向過程編程,首先考慮要遵循的步驟,然后考慮如何表示這些數(shù)據(jù)
2.oop編程,首先會考慮數(shù)據(jù),包括數(shù)據(jù)的表示和數(shù)據(jù)的使用
2.類和對象
面向?qū)ο蟮木幊塘鞒?#xff1a;
1.抽象:從具體食物抽取共同的本質(zhì)特征,【處理復(fù)雜問題的技巧–簡化、抽象】
地主對象:外表特征–胖,留兩撇胡子,兩顆大金牙;行為特點–先出牌,多摸三張牌
2.用類封裝:將抽象轉(zhuǎn)換為用戶定義類型的工具,將數(shù)據(jù)表示和操作數(shù)據(jù)的方法組合成一個整體。類的實例成為對象(對象的集合就是類,還可以這么理解:類就是對象模版),類中的變量和函數(shù)稱為成員。
地主類:
成員變量:名稱、積分、手牌
成員函數(shù):摸牌、出牌、產(chǎn)看積分
類的聲明:使用class/struct 關(guān)鍵字聲明,
兩者的區(qū)別:使用class聲明的類默認成員是私有的(private),struct聲明的類默認成員是共有的(public)。
推薦使用class聲明類;struct聲明結(jié)構(gòu),只包含數(shù)據(jù)POD,老式數(shù)據(jù)
class 類名{};
struct 類名{};
頭文件中聲明類(.h/.cpp),專門有一個類名.cpp文件實現(xiàn)類。
demo1:地主類的實現(xiàn)版本1
–LandOwnerV1.cpp 文件中既聲明又實現(xiàn),包含main 函數(shù)的main.cpp文件中調(diào)用
// mian.cpp 文件 #include "LandOwnerV1.cpp" int main(){// 類,對象實驗LandOwnerV1 landOwner1; // 聲明了一個LandOwner1類型的變量landowner1// 調(diào)用對象的成員方法, 不能直接使用對象的私有成員// landOwner1.cards[0] = 0; 'cards' is a private member of 'LandOwnerV1' ,直接報錯landOwner1.TouchCard(100);return 0; } // LandOwnerV1.cpp 文件既聲明又實現(xiàn) #include <iostream> using namespace std; // .hpp 一般包含實現(xiàn)的內(nèi)聯(lián)函數(shù),通常用于模版類這種聲明與實現(xiàn)共存的情況 // 建議:只要不是純模版,一律使用.h 作為頭文件后綴, .cpp 作為函數(shù)的實現(xiàn)文件 // 地主類的聲明、實現(xiàn) class LandOwnerV1 {private:string name; // 名稱long score; // 積分int cards[20]; // 手牌數(shù)組public :LandOwnerV1() {}; // 默認構(gòu)造函數(shù)~LandOwnerV1() {}; // 默認析構(gòu)函數(shù)void TouchCard(int CardCount){// 暫時省略函數(shù)實現(xiàn)cout << name << "摸了" << CardCount << "張牌" << endl;}void ShowScore(){cout << name << "當前的積分為:" << score << endl;}};輸出
摸了100張牌demo2:地主類的實現(xiàn)版本2
–LandOwnerV2.h中聲明,LandOwnerV2.cpp中實現(xiàn),main.cpp文件中調(diào)用
成員函數(shù)沒有調(diào)用成功
// mian.cpp 文件 #include "LandOwnerV2.h" // 關(guān)注.h 文件 using namespace std; int main(){LandOwnerV2 landowner2;landowner2.name = "小明";//landowner2.TouchCard(20); // 這個方法實現(xiàn)不了cout << landowner2.name << endl;return 0; } // LandOwnerV2.h #include <iostream> using namespace std; // .hpp 一般包含實現(xiàn)的內(nèi)聯(lián)函數(shù),通常用于模版類這種聲明與實現(xiàn)共存的情況 // 建議:只要不是純模版,一律使用.h 作為頭文件后綴, .cpp 作為函數(shù)的實現(xiàn)文件 // 地主類的聲明class LandOwnerV2 {private:long score; // 積分int cards[20]; // 手牌數(shù)組public :string name; // 名稱LandOwnerV2(); // 構(gòu)造函數(shù)聲明~LandOwnerV2(); // 析構(gòu)函數(shù)聲明 void TouchCard(int); // 聲明摸牌函數(shù)void PlayCard(int); // 聲明出牌函數(shù)void ShowScore(); // 聲明產(chǎn)看積分函數(shù) }; // LandOwnerV2.cpp #include <iostream> #include "LandOwnerV2.h" using namespace std;LandOwnerV2::LandOwnerV2() {//ctor }void LandOwnerV2::TouchCard(int CardCount){cout << name << "摸了" << CardCount << "張牌" << endl; } void LandOwnerV2::ShowScore(){cout << name << "當前的積分為:" << score << endl; }LandOwnerV2::~LandOwnerV2() {//dtor }(xcode 太不友好了,寫到類分文件時就無法編譯,棄坑!轉(zhuǎn)向CLION,友好很多。)
3.訪問修飾符
public: 修飾的成員在任意地方都可以訪問
private:修飾的成員只能在類中或者友元函數(shù)中訪問, 私有屬性可以習(xí)慣性在名字前面加一個_
protected:修飾的成員可以在類中函數(shù)、子類函數(shù)、友元函數(shù)中訪問
(數(shù)據(jù)隱藏:不希望別人隨意操作,對應(yīng)的操作叫做封裝)
在修飾關(guān)鍵字放在類定義的關(guān)鍵字中,加冒號,無修飾關(guān)鍵字默認為private
class 類名{ 修飾符:成員類標; };demo3:外部修改成員變量不安全(版本3)
非私有成員,會被直接修改–修改地主積分
// mian.cpp 文件 #include <iostream> #include "LandOwnerv3.h" using namespace std; int main(){// 訪問修飾符的實驗LandOwnerv3 landOwner3;landOwner3.name = "巴依老爺";// 修改地主積分landOwner3.score = 100;landOwner3.ShowScore(landOwner3.score);return 0; } // LandOwnerv3.h 文件 // Created by 陳瑩瑩 on 2021/1/28. #include <iostream> #ifndef HELLOWORLD_LANDOWNERV3_H #define HELLOWORLD_LANDOWNERV3_H using namespace std; class LandOwnerv3 {int cards[20]; // 手牌數(shù)組 public :string name;long score; // 積分LandOwnerv3(); // 構(gòu)造函數(shù)聲明, 沒有返回值~LandOwnerv3(); // 析構(gòu)函數(shù)聲明void TouchCard(int); // 聲明摸牌函數(shù)void PlayCard(int); // 聲明出牌函數(shù)void ShowScore(int); // 聲明產(chǎn)看積分函數(shù) }; #endif //HELLOWORLD_LANDOWNERV3_H // LandOwnerv3.cpp 文件 // Created by 陳瑩瑩 on 2021/1/28. // 用來演示封裝的基本概念 #include <iostream> #include "LandOwnerv3.h" using namespace std; LandOwnerv3::LandOwnerv3() {//ctor } void LandOwnerv3::ShowScore(int score){cout << name << "當前的積分為:" << score << endl; }LandOwnerv3::~LandOwnerv3() {//dtor }輸出:
巴依老爺當前的積分為:100demo4: 使用封裝防止直接修改成員變量(版本3)
但是如此操作使得大家可以隨意修改這個積分,有一些不合理的積分就會出現(xiàn)。為了解決積分被賦值為不合理的情況,需要將成員變量score進行封裝(使用方法來實現(xiàn)對成員的封裝)
demo4:類封裝概念,get/set方法
輸出:
巴依老爺當前的積分為:0demo5:進一步封裝:設(shè)置/獲取名字,修改積分(版本4)
// mian.cpp 文件 #include <iostream> #include "LandOwnerv41.h" using namespace std; int main(){// 訪問修飾符的實驗LandOwnerv41 landOwner4;landOwner4.SetName("巴依老爺");cout << landOwner4.GetName() << endl;// 修改地主積分landOwner4.SetScore(-100);landOwner4.ShowScore();return 0; } // LandOwnerv41.h 文件 // Created by 陳瑩瑩 on 2021/1/29. #ifndef HELLOWORLD_LANDOWNERV41_H #define HELLOWORLD_LANDOWNERV41_H#include <iostream> using namespace std; class LandOwnerv41 {long score; // 積分int cards[20]; // 手牌數(shù)組string name; public :LandOwnerv41(); // 構(gòu)造函數(shù)聲明, 沒有返回值~LandOwnerv41(); // 析構(gòu)函數(shù)聲明void TouchCard(int); // 聲明摸牌函數(shù)void PlayCard(int); // 聲明出牌函數(shù)void ShowScore(); // 聲明產(chǎn)看積分函數(shù)// 定義成內(nèi)聯(lián)函數(shù)即可void SetScore(long lScore){// 通過條件判斷封裝了score的賦值過程if(lScore < 0){score = 0;}else{score = lScore;}}string GetName(){return name;}void SetName(string lName){name = lName;}}; #endif //HELLOWORLD_LANDOWNERV41_H // LandOwnerv41.cpp 文件 // Created by 陳瑩瑩 on 2021/1/29. #include "LandOwnerv41.h" #include <iostream> using namespace std; LandOwnerv41::LandOwnerv41() {//ctor } void LandOwnerv41::ShowScore(){cout << name << "當前的積分為:" << score << endl; }LandOwnerv41::~LandOwnerv41() {//dtor }4.構(gòu)造函數(shù)與析構(gòu)函數(shù)(重點)
構(gòu)造函數(shù):與類同名,沒有返回值
構(gòu)造函數(shù)的作用:給編譯器看的,編譯器在對象被創(chuàng)建時,為對象分配內(nèi)存空間,并自動調(diào)用構(gòu)造函數(shù)以完成成員的初始化
構(gòu)造函數(shù)的種類:無參數(shù)構(gòu)造,一般構(gòu)造(重載構(gòu)造),拷貝構(gòu)造。(本節(jié)主要介紹:無參構(gòu)造,一般構(gòu)造)
4.1默認構(gòu)造函數(shù)
demo6: 使用構(gòu)造函數(shù)進行成員變量的初始化
// mian.cpp 文件 //演示構(gòu)造函數(shù) #include "LandOwnerv41.h" using namespace std; int main(){LandOwnerv41 landOwnerv4; // 省略了默認構(gòu)造LandOwnerv41 landOwnerv4(); // 標準寫法,但是不調(diào)用默認構(gòu)造函數(shù)了?--不輸出內(nèi)容了return 0; } // LandOwnerv41.h 文件 // 與demo5一致 // LandOwnerv41.cpp 文件 // Created by 陳瑩瑩 on 2021/1/29. // #include "LandOwnerv41.h" #include <iostream> #include <memory.h> using namespace std; LandOwnerv41::LandOwnerv41() {cout << "LandOwnerV41的無參數(shù)構(gòu)造函數(shù)(默認構(gòu)造)被調(diào)用!" << endl;name = "默認地主";score = 0;//將用戶的手牌數(shù)組初始化為0memset(cards, 0, sizeof(cards)/sizeof(cards[0]));cout << "初始化的結(jié)果如下:" << endl;cout << "名字:" << name << endl;cout << "積分:" << score << endl;cout << "手牌數(shù)組:" ;for(int i=0; i < sizeof(cards)/sizeof(cards[0]); i++){cout << cards[i] << "\t";}cout << endl; } void LandOwnerv41::ShowScore(){cout << name << "當前的積分為:" << score << endl; }LandOwnerv41::~LandOwnerv41() {//dtor }為啥手牌數(shù)組的初始化不是全為0?
LandOwnerV41的無參數(shù)構(gòu)造函數(shù)(默認構(gòu)造)被調(diào)用! 初始化的結(jié)果如下: 名字:默認地主 積分:0 手牌數(shù)組:0 0 0 0 0 0 0 0 -375207560 32766 -375207584 32766 0 1 0 0 0 0 0 0默認構(gòu)造顯式寫法:
LandOwnerV4() = default;
注意:
1.如果創(chuàng)建的類中未書寫任何構(gòu)造函數(shù),系統(tǒng)會自動生成默認的無參構(gòu)造函數(shù)(函數(shù)為空,什么都不做)
2.如果書寫了構(gòu)造函數(shù),系統(tǒng)不會自動生成默認構(gòu)造函數(shù),如果希望有一個這樣的無參數(shù)構(gòu)造函數(shù),需要自己顯示書寫LandOwnerV4() = default;
4.2 帶參構(gòu)造函數(shù)
語法:
類名::構(gòu)造(類型1 參數(shù)1, 類型2 參數(shù)2, ....){// 相關(guān)初始化方法 }demo7:學(xué)生類構(gòu)建–堆內(nèi)存對象/棧內(nèi)存對象
1.棧內(nèi)存中的對象(類似于函數(shù)聲明),
具體對象由系統(tǒng)創(chuàng)建并釋放,不用擔心內(nèi)存泄露。
聲明周期只在聲明區(qū)域的大括號內(nèi)。
棧內(nèi)存的優(yōu)勢存取速度快(僅次于寄存器),缺點棧內(nèi)存中的數(shù)據(jù)大小生存期是確定的,缺乏靈活性。
自定義類型名 對象名;
Student stu();
Student stu;
2.堆內(nèi)存中的對象(需要new關(guān)鍵字)
p_stu1是指針,必須使用delete釋放
使用靈活可以賦給全局變量,可以把對象作為函數(shù)的返回值
用好了
Student *p_stu1= new Student();
Student *p_stu2= new Student();
auto *p_stu3= new Student(); // auto 自動類型判斷,不推薦使用,sizeof 會報錯
類對象推薦放在堆內(nèi)存中,即使用new來創(chuàng)建對象。
// mian.cpp 文件 #include <iostream> #include "Student.h" using namespace std; int main(){// 演示構(gòu)造函數(shù),實質(zhì)就是函數(shù)重載Student stu1;Student stu2("馬化騰","普通家庭"); // 在棧內(nèi)存中直接分配空間,速度塊// 如果構(gòu)造函數(shù)中只有一個參數(shù),且單參數(shù)構(gòu)造函數(shù)只有一個,可以直接使用賦值操作進行初始化// Student stu4 = 45stu2.showInfo();// 學(xué)生指針類型, 使用new 分配內(nèi)存空間Student * stu5 = new Student("杰克馬", "毀創(chuàng)阿里"); // 在堆內(nèi)存中分配空間// 類指針訪問方法要使用 ->stu5 ->showInfo();return 0; }輸出結(jié)果:
默認構(gòu)造函數(shù) 設(shè)置帶參構(gòu)造 普通家庭馬化騰 設(shè)置帶參構(gòu)造 毀創(chuàng)阿里杰克馬 // Student.h 文件 // // Created by 陳瑩瑩 on 2021/2/2. // #ifndef HELLOWORLD_STUDENT_H #define HELLOWORLD_STUDENT_H #include <iostream> using namespace std;class Student { private:string m_name;string m_desc;int m_age; public:Student(); // 默認構(gòu)造函數(shù)Student(string, string);~Student();void showInfo();}; #endif //HELLOWORLD_STUDENT_H // Student.cpp 文件 // // Created by 陳瑩瑩 on 2021/2/2. // #include <iostream> #include "Student.h" using namespace std;Student::Student() {cout << "默認構(gòu)造函數(shù)" << endl; } //Student::Student(string name, string desc){ // // 參數(shù)列表不同,函數(shù)重載 // m_name = name; // m_desc = desc; // cout << "設(shè)置帶參構(gòu)造" << endl; //} //初始化參數(shù)列表的寫法,和上上面的帶參數(shù)構(gòu)造方法完全相同 Student::Student(string name, string desc):m_name(name), m_desc(desc){cout << "設(shè)置帶參構(gòu)造" << endl; };void Student::showInfo() {cout << m_desc << m_name << endl; } Student::~Student() {}4.3 析構(gòu)函數(shù)
對象銷毀時自動調(diào)用的特殊成員函數(shù), 析構(gòu)函數(shù)一般用來完成清理工作。
析構(gòu)函數(shù)名稱在類名前加一個~,析構(gòu)函數(shù)沒有參數(shù),只能有一個
在棧內(nèi)存中構(gòu)造的對象,在棧區(qū)(mian函數(shù))銷毀時,類對象會被自動銷毀。在堆內(nèi)存中構(gòu)建的類對象,需要手動釋放。
在析構(gòu)函數(shù)內(nèi)部需要釋放(delete)掉在構(gòu)造函數(shù)中手動分配(new)的空間(對象內(nèi)部的成員變量)。
1.析構(gòu)函數(shù)用來釋放對象使用的資源,并銷毀對象的非static數(shù)據(jù)成員.
2.無論何時一個對象被銷毀,都會自動調(diào)用析構(gòu)函數(shù)(隱式析構(gòu))
demo8:學(xué)生類析構(gòu)函數(shù)演示
類對象推薦放在堆內(nèi)存中,即使用new來創(chuàng)建對象。
// mian.cpp 文件 #include <iostream> #include "Student.h" using namespace std; int main(){// 演示構(gòu)造函數(shù),實質(zhì)就是函數(shù)重載Student stu1;Student stu2("馬化騰","普通家庭"); // 在棧內(nèi)存中直接分配空間,速度塊// 如果構(gòu)造函數(shù)中只有一個參數(shù),且單參數(shù)構(gòu)造函數(shù)只有一個,可以直接使用賦值操作進行初始化// Student stu4 = 45stu2.showInfo();// 學(xué)生指針類型, 使用new 分配內(nèi)存空間Student * stu5 = new Student("杰克馬", "毀創(chuàng)阿里"); // 在堆內(nèi)存中分配空間// 類指針訪問方法要使用 ->stu5 ->showInfo();return 0; }輸出結(jié)果:
默認構(gòu)造函數(shù) 設(shè)置帶參構(gòu)造 普通家庭馬化騰 設(shè)置帶參構(gòu)造 毀創(chuàng)阿里杰克馬 杰克馬被釋放 # 杰克馬為啥被釋放了? 馬化騰被釋放 被釋放 // Student.h 文件 // 與demo7一樣 // Student.cpp 文件 // // Created by 陳瑩瑩 on 2021/2/2. // #include <iostream> #include "Student.h" using namespace std;Student::Student() {cout << "默認構(gòu)造函數(shù)" << endl; } //Student::Student(string name, string desc){ // // 參數(shù)列表不同,函數(shù)重載 // m_name = name; // m_desc = desc; // cout << "設(shè)置帶參構(gòu)造" << endl; //} //初始化參數(shù)列表的寫法,和上上面的帶參數(shù)構(gòu)造方法完全相同 Student::Student(string name, string desc):m_name(name), m_desc(desc){cout << "設(shè)置帶參構(gòu)造" << endl; };void Student::showInfo() {cout << m_desc << m_name << endl; } Student::~Student() {cout << m_name << "被釋放" << endl; }5.this指針(重點)
(類似于于python中的self,在python中顯式傳遞self參數(shù))
每個成員函數(shù)(包括構(gòu)造函數(shù)和析構(gòu)函數(shù))都有一個this指針。this指針指向調(diào)用對象,可以通過this關(guān)鍵字訪問當前對象的成員。
this 在成員函數(shù)執(zhí)行前就已經(jīng)創(chuàng)建,在析構(gòu)函數(shù)之后被銷毀。
->this 指針的類型為*const,為右值;(可以賦值)
->this指針本身不占用大小,并不是對象的一部分,用sizeof 測不出來大小
->this指針作用域在成員函數(shù)內(nèi)部;
->this指針是類成員函數(shù)的第一個默認隱含參數(shù),編譯器自動維護傳遞,編寫者不能顯式傳遞。
->在類非靜態(tài)成員函數(shù)中才可以使用this指針,其他任何函數(shù)都不可以(static是先于類實例存在的,this還沒有創(chuàng)建)
this 返回當前對象的引用,太難用了-- Student & GetSuperScholars(Student &);
demo9:學(xué)霸返回引用的使用
//mian.cpp #include <iostream> #include "Student.h" using namespace std; int main(){Student *ptr_stu1 = new Student("迪麗熱巴","微胖女孩");ptr_stu1->AddScore(78.9);ptr_stu1->AddScore(77.9);ptr_stu1->AddScore(72.9);ptr_stu1->AddScore(79.9);ptr_stu1->AddScore(800);ptr_stu1->showInfo();Student stu2("劉強東","不愛美人");stu2.AddScore(78.9);stu2.AddScore(77.9);stu2.AddScore(72.9);stu2.AddScore(79.9);stu2.AddScore(90);stu2.showInfo();// Student scholar1 = stu2.GetSuperScholars(*ptr_stu1); 返回new出來的結(jié)果,接受的確實棧類型,矛盾,空間釋放的時候會出問題 // Student scholar2 = ptr_stu1->GetSuperScholars(stu2);Student &scholar1 = stu2.GetSuperScholars(*ptr_stu1); //返回迪麗熱巴的引用,Student &scholar2 = ptr_stu1->GetSuperScholars(stu2); //返回迪麗熱巴的引用cout << "學(xué)霸是" << scholar1.GetName() << "\t" << scholar2.GetName() << endl;delete ptr_stu1;return 0;//scholar1 棧內(nèi)存中定義的,main 結(jié)束后會自動釋放//scholar2 棧內(nèi)存中定義的,main 結(jié)束后會自動釋放 } //Student.h // // Created by 陳瑩瑩 on 2021/2/2. // #ifndef HELLOWORLD_STUDENT_H #define HELLOWORLD_STUDENT_H #include <iostream> using namespace std;class Student { private:string m_name;string m_desc;int m_age;float *scores; // 學(xué)生的分數(shù)數(shù)組,在某次構(gòu)造的時候進行初始化int scoreCount; // 學(xué)生成績的個數(shù)public:Student(); // 默認構(gòu)造函數(shù)Student(string, string);~Student();void showInfo();void InitScores(); // 初始化學(xué)生的成績數(shù)組,默認分配一個元素空間void AddScore(float score);// 返回值是引用時,是非常危險的。this可以直接修改屬性,建議在函數(shù)聲明處加一個const,限制在該函數(shù)內(nèi)部不能通過this指針修改屬性,太麻煩了,要該的地方太多了Student & GetSuperScholars(Student &); //返回學(xué)霸對象// 參數(shù)處加const 保證不對該參數(shù)進行修改。float GetTotal();string GetName() {return m_name;}};#endif //HELLOWORLD_STUDENT_H //Student.cpp // // Created by 陳瑩瑩 on 2021/2/2. // #include <iostream> #include "Student.h" using namespace std;Student::Student() {cout << "默認構(gòu)造函數(shù)" << endl;InitScores(); } //Student::Student(string name, string desc){ // // 參數(shù)列表不同,函數(shù)重載 // m_name = name; // m_desc = desc; // cout << "設(shè)置帶參構(gòu)造" << endl; //} //初始化參數(shù)列表的寫法,和上上面的帶參數(shù)構(gòu)造方法完全相同 Student::Student(string name, string desc):m_name(name), m_desc(desc){cout << "設(shè)置帶參構(gòu)造" << endl;InitScores(); };void Student::showInfo() {cout << m_desc << m_name << endl;for(int i = 0; i < scoreCount-1; i++){cout << this->scores[i] << "\t";}cout << endl; } // C的類方法寫(我這么寫編譯不過) //void MyShow(const Student* this){ // this-> //} void Student::InitScores() {this -> scores = new float [1];this -> scoreCount = 1; } void Student::AddScore(float score) {this -> scores[this->scoreCount -1] = score;// 1. 創(chuàng)建一個新數(shù)組,分配scoreCount+1 個空間// 2. 復(fù)制愿數(shù)組中的內(nèi)容到新數(shù)組中// 3. scoreCount++// 4. scores指向新數(shù)組float *newScores = new float [scoreCount + 1];float *oldScores = scores;memcpy(newScores, scores, sizeof(float) * scoreCount);scoreCount++;scores = newScores;delete oldScores; // 刪除原來的指針 } Student & Student::GetSuperScholars(Student &otherstu){// otherstu 要對比的另一學(xué)生對象// 返回總分比較大的那個學(xué)生對象// 分別計算兩個學(xué)生的總分if(this->GetTotal() > otherstu.GetTotal()){return *this;}else{return otherstu;}} float Student::GetTotal(){float sum = 0;for(int i = 0; i < scoreCount; i++){sum += scores[i];}return sum;} Student::~Student() {cout << m_name << "被釋放" << endl;delete this -> scores;}輸出
設(shè)置帶參構(gòu)造 微胖女孩迪麗熱巴 78.9 77.9 72.9 79.9 800 設(shè)置帶參構(gòu)造 不愛美人劉強東 78.9 77.9 72.9 79.9 90 學(xué)霸是迪麗熱巴 迪麗熱巴 迪麗熱巴被釋放 劉強東被釋放小結(jié):類就是自己定義的數(shù)據(jù)類型,對象就是變量
總結(jié)
以上是生活随笔為你收集整理的C++(14)--面向对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++:17---函数指针
- 下一篇: C++(STL):03---智能指针之s