孙鑫VC++深入详解第二章学习笔记
第二章 掌握C++
2.1 從結(jié)構(gòu)到類
2.1.1 結(jié)構(gòu)體的定義
程序2.1
#include <iostream> using namespace std; //error C1083: 無法打開包括文件:“iostream.h”: No such file or directorystruct point {int x, y; //狀態(tài)void output() //行為{cout << "x="<< x << endl << "y=" << y << endl;//endl是換行符} }pt;//注意分號int main() {cout << "請輸入x和y的值:" << endl;cin >> pt.x;cin >> pt.y;pt.output(); //注意括號return 0; }2.1.2 結(jié)構(gòu)體與類
在C++中,結(jié)構(gòu)體(struct)和類(class)可以通用。
區(qū)別在于訪問控制的差異:
程序2.2:將程序2.1中的struct point修改為class point
class point //類:抽象出一些事物共有的屬性 { public:int x, y;void output(){cout << "x="<< x << endl << "y=" << y << endl;} }pt; //實例化了一個對象==類的實例化:具有具體的屬性值2.2 C++的特性
2.2.1 類與對象
類:抽象出一些事物共有的屬性;
對象:有具體的屬性值。
2.2.2 構(gòu)造函數(shù)
作用:在定義對象的同時,對成員變量進行初始化;
創(chuàng)建對象本身(分配內(nèi)存)
規(guī)定:構(gòu)造函數(shù)的名字和類名相同(唯一性);
沒用返回值;
可以有參數(shù)。
注意:
2.2.3 析構(gòu)函數(shù)
~類名(); //對象生命周期結(jié)束,釋放其占用資源;是一個對象最后調(diào)用的成員函數(shù)
注意:析構(gòu)函數(shù)不允許有返回值,更不允許有參數(shù),并且一個類中只有一個構(gòu)造函數(shù)。
代碼2.3:構(gòu)造函數(shù)和析構(gòu)函數(shù)
2.2.4 函數(shù)的重載
條件:函數(shù)參數(shù)類型、個數(shù)不同才能構(gòu)成重載。
注意:
代碼2.4 函數(shù)的重載
class point { public:int x , y;point() //函數(shù)1{x = 0;y = 0;}point(int a, int b) //重載,函數(shù)2{x = a;y = b;} };void main() {point pt(5,5); //C++根據(jù)參數(shù)類型和個數(shù),執(zhí)行函數(shù)2 }2.2.5 this指針
this->x是對成員變量進行賦值;
x是對形參賦值。
2.2.6 類的繼承
2.2.6.1 繼承
例如:class fish : public animal{};
2.2.6.2 在子類中調(diào)用父類帶參數(shù)的構(gòu)造函數(shù)
例如:父類構(gòu)造函數(shù): animal(int h , int w){}
則在構(gòu)造子類時,應(yīng)該顯式地去調(diào)用父類的帶參數(shù)構(gòu)造函數(shù): fish():animal(400,300){}
2.2.6.3 類的繼承及類中成員的訪問特性
3種訪問權(quán)限修飾符:
public:定義的成員可以在任何地方被訪問;
protected:定義的成員只能在該類及其子類中訪問;
private:定義的成員只能在該類自身中訪問。==>不能被子類繼承
3種繼承方式:
2.2.6.4 多重繼承
定義形式:class B: public C , public D
了解父類表順序?qū)φ{(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)的影響。對于上面的例子,先構(gòu)造C再構(gòu)造D,先析構(gòu)D再析構(gòu)C。
2.2.7 虛函數(shù)與多態(tài)性、純虛函數(shù)
2.2.7.1虛函數(shù)與多態(tài)性
程序 2.5
(P49)... class animal { public:...void breathe(){cout<<"animal breathe"<<endl;} /*注意此時不是虛函數(shù)*/ };class fish : public animal { public:...void breathe(){cout<<"fish bubble"<<endl;} } void breathetest(animal* pan) {pan->breathe(); }void main() {animal* pan; //指向animal類的指針panfish fi;pan = &fi; //將fish類的對象fi的地址直接賦給指向animal類的指針變量panbreathetest(pan); }/*輸出animal breathe*/1、fish對象也是一個animal類,C++自動進行類型轉(zhuǎn)換;反之,不能把animal對象看成fish對象。
2、當(dāng)我們將fish轉(zhuǎn)化為animal時,該對象就會被認(rèn)為是原對象內(nèi)存模型的上半部分。
3、將父類函數(shù)修改為虛函數(shù),輸出結(jié)果為fish bubble。
(P49)...virtual void breathe() //虛函數(shù)... /*輸出fish bubble*/虛函數(shù):用virtual關(guān)鍵字申明的函數(shù)–>多態(tài)性;
遲邦定:編譯時并不確定具體調(diào)用的函數(shù),而是在運行時依據(jù)對象的類型來確認(rèn)調(diào)用的是哪一個函數(shù)。
概括(用法):在父類的函數(shù)前加上virtual關(guān)鍵字,在子類重寫該函數(shù),運行時將會根據(jù)對象的實際類型來調(diào)用相應(yīng)的函數(shù)。
2.2.7.2 純虛函數(shù)
寫法:
virtual void breathe() = 0 ; //1、等于0;2、無函數(shù)體注意:子類如果有對父類虛函數(shù)的覆蓋定義,無論該覆蓋定義是否有virtual,都是虛函數(shù)。
2.2.8函數(shù)的覆蓋和隱藏
2.2.8.1 覆蓋
1、覆蓋(P52):發(fā)生在父類和子類之間 的 函數(shù)完全一樣(函數(shù)名、參數(shù)列表),編譯器根據(jù)實際類型確定要調(diào)用的函數(shù)。
2、對比重載:重載是發(fā)生在同一個類當(dāng)中;覆蓋是發(fā)生在父類和子類之間
程序2.6 函數(shù)的覆蓋
class animal { public:virtual void breathe(){cout<<"animal breathe"<<endl;} };class fish : public animal { public:void breathe() //覆蓋{cout<<"fish bubble"<<endl;} };void main() {fish fi;fi.breathe(); } /*輸出fish bubble*/2.2.8.2 隱藏
兩種父類函數(shù)隱藏的情況:
區(qū)別隱藏與覆蓋:覆蓋是發(fā)生在父類與子類之間,兩個函數(shù)必須完全相同且都是虛函數(shù)。否則就是隱藏。
2.2.9 引用
定義形式:
int a; int &b = a; //引用必須在申明時就初始化,與a綁定;后面不會再與其他變量綁定注意:
程序2.7 引用示例
#include <iostream> using namespace std; //換成引用意思表達更清晰:/*以下為用指針交換數(shù)據(jù)*/ void change(int* a,int* b); //void change(int& a,int& b);int main() {int x = 5, y = 3;cout << "x=" << x << endl;cout << "y=" << y << endl;change(&x,&y); //是對x和y的地址互換還是對x和y互換? change(x,y);cout << "x=" << x << endl;cout << "y=" << y << endl;return 0; }void change(int* a, int* b) //void change(int a,int b) { //{int c; // int c;c = *a; // c = a;*a = *b; // a = b;*b = c; // b = c; } //}2.2.10 C++類設(shè)計習(xí)慣和頭文件重復(fù)包含問題的解決
1、頭文件存放類的定義及類成員函數(shù)的聲明;
源文件存放類中成員函數(shù)的實現(xiàn)。
2、注意文件包含;
#include "animal.h" //"",從當(dāng)前目錄開始搜索,然后是系統(tǒng)目錄和PATH環(huán)境變量所列出的目錄
#include <iostream> //<>,從系統(tǒng)目錄開始搜索,然后是PATH環(huán)境變量所列出的目錄。``不搜索當(dāng)前目錄
注意子類的頭文件中也要包含父類的頭文件,如fish.h中的#include “animal.h”。
3、::是作用域表示符,表明函數(shù)或數(shù)據(jù)成員屬于哪個類;
前面如果不跟類名,表示全局函數(shù)(即非成員函數(shù))或全局?jǐn)?shù)據(jù)。
4、在頭文件中聲明函數(shù)時用了virtual,在源文件中就不用寫virtual。
5、要解決類重復(fù)定義的問題,要使用條件預(yù)處理指令(如課后程序animal.h和fish.h所示)
程序2.8 條件預(yù)處理指令解決類重復(fù)定義的問題
#ifndef ANIMAL_H_H //如果沒有定義ANIMAL_H_H,就定義ANIMAL_H_H,接著申明animal類//如果定義過了ANIMAL_H_H,直接跳至endif #define ANIMAL_H_Hclass animal { };#endif2.2.11 VC++程序編譯連接的原理與過程
1、編譯:頭文件不參與編譯
源文件單獨編譯
XXX.obj目標(biāo)文件
2、鏈接
編譯鏈接過程如下。
課后程序
animal.h
/*animal.h*/#ifndef ANIMAL_H_H //如果沒有定義ANIMAL_H_H,就定義ANIMAL_H_H,接著申明animal類//如果定義過了ANIMAL_H_H,直接跳至endif #define ANIMAL_H_Hclass animal { public:animal();~animal();void eat();void sleep();virtual void breathe(); };#endifanimal.cpp
/*animal.cpp*/#include <iostream> #include "animal.h"using namespace std;animal::animal() { }animal::~animal() { }void animal::eat() { }void animal::sleep() { }void animal::breathe() //在頭文件中有virtual,則在源文件中不用加virtual {cout << "animal breathe" << endl; }fish.h
/*fish.h*/#include "animal.h" //fish類從animal類繼承#ifndef FISH_H_H#define FISH_H_H class fish :public animal //結(jié)構(gòu)體、類名后面沒有括號() { public:void breathe(); };#endiffish.cpp
/*fish.cpp*/#include <iostream> #include "fish.h"using namespace std;void fish::breathe() {cout << "fish bubble" << endl; }main.cpp
/*main.cpp*/#include "animal.h" #include "fish.h"void breathetest(animal* pan) {pan->breathe(); }int main() {animal* pan;fish fi;animal an;pan = &fi;breathetest(pan);pan = &an;breathetest(pan);return 0; }運行結(jié)果
問題及反思
vs2019編程出現(xiàn)的問題:
1、建立C++空項目后,要在右側(cè)工程的源文件的文件夾下創(chuàng)建XXX.cpp文件;
否則編譯時無法啟動程序XXX.exe,系統(tǒng)找不到指定文件。
2、頭文件#include <iostream.h>后添加using namespace std;
否則報錯:error C1083: 無法打開包括文件:“iostream.h”: No such file or directory
3、定義結(jié)構(gòu)體或類時,別忘記最后的分號;結(jié)構(gòu)體名或類名后面沒有小括號;
4、引用成員函數(shù)別忘記括號:pt.output();
5、.sln為項目文件
參考文獻
[1]https://blog.csdn.net/weixin_43751983/article/details/91147918this指針
[2]孫鑫.VC++深度詳解修訂版[M]. 北京:電子工業(yè)出版社, 2012. 27-62.
總結(jié)
以上是生活随笔為你收集整理的孙鑫VC++深入详解第二章学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二轮自平衡车
- 下一篇: mfc编程 孙鑫_孙鑫c++视频教程百度