C++全套視頻教程【qt版】


- ::作用域 可以在局部中用全局變量
2.命名空間 防止類庫沖突 namespace

3.你知道在命名空間外面定義成員函數(shù)嗎?(無名的namespace只能在本文件使用類似于static)
namespace A{
int a;
func();
}
void A::func(){
}
4.using 使用命名空間
那么下面調(diào)用優(yōu)先從命名空間找
代價(jià)容易沖突

圖例,雖然使用using,但是訪問的是局部變量a
只能veryLongName::a來使用
5.const 全局只讀變量

上圖為老師翻車實(shí)例(在c語言中)
const int num = 10;(文件1)
extern const int num;(文件2)
本來是要證明雖然const過的變量不能直接賦值,但可以通過取地址來間接賦值
如圖中:int *p = (int *)#
*p = 2000;
但是操作失敗了,原因是老師定義的const變量是全局變量,使用const后會(huì)在文字常量區(qū)存放,只可讀不可改,因此只有用const在局部變量中在棧區(qū)開辟可讀可寫
(在cpp中)
而const在cpp中修飾全局變量,為內(nèi)部鏈接,就是只能在當(dāng)前文件中生效,不能直接用于其他源文件,非要使用可以這樣
extern const int num = 10;(文件1)
extern const int num;(文件2)
const int date = 10;(只有這樣初始化才放入符號(hào)表)
const的data存在符號(hào)表中,類似define,只有在extern或取地址時(shí)才會(huì)給data分配地址,由于存在符號(hào)表里,輸出data依舊是原始值,因此改了沒弔用
其他情況如下圖

#P22
6.cpp中的引用reference(能不用指針就不用)
格式:int num = 10;
int &a = num;(引用)
int *a = #(取地址,注意區(qū)別)
給數(shù)組起別名
int arr[5] = {};
int (&my_arr)[5] = arr;

typedef int TYPE_ARR[5];
TYPE_ARR &my_arr = arr
引用可以在函數(shù)內(nèi)部改變外部的數(shù)值(作為函數(shù)的參數(shù))

引用作為函數(shù)返回值
int& my_data(){
static int num = 10;
return num;
}

引用的本質(zhì)原理:使用指針常量(只要了解)
int num = 10;
int &a = num;
//計(jì)算機(jī)內(nèi)部:int *const a = #
常引用,保證只讀不改,用const修飾一下

const int &num = 10;(10是const int類型,常量引用)
7.內(nèi)聯(lián)函數(shù)(是真正的man不是[doge]func)
像預(yù)定義宏一樣展開,不占用開銷,做法是:
inline int func(int a){return ;} 函數(shù)體和聲明寫一起(以空間換時(shí)間)
inline 是給編譯器的建議
8.函數(shù)的默認(rèn)參數(shù)
從左往右,有默認(rèn)則其后全部設(shè)置默認(rèn)
建議函數(shù)聲明設(shè)置缺省參數(shù)
extern int func01(int x = 2,int y =3){
return $$$;
}
9.函數(shù)重載(多態(tài)性)
同一作用域 參數(shù)個(gè)數(shù)不同 參數(shù)類型不同 參數(shù)順序不同
PS:函數(shù)和默認(rèn)參數(shù)函數(shù)小心二義性
10.extern "C" cpp中引用c函數(shù)有一套完整流程

#if __cplusplus
11.封裝的概念
把變量和函數(shù)合成一個(gè)整體,封裝在一個(gè)類中
跟Javabeans很像啊

對(duì)于類的外部訪問權(quán)限才有意義
public:公共
private:私有
protect:保護(hù)
數(shù)據(jù)私有方法公公有,可以借助公有訪問私有
成員數(shù)據(jù)占類的大小,函數(shù)不占
成員函數(shù)類內(nèi)聲明,類外定義

void Date::setNum(){}
alt+回車快速添加定義
類定義在.h 成員函數(shù)寫在.cpp 在main.cpp中測(cè)試
12.構(gòu)造函數(shù)和析構(gòu)函數(shù)

構(gòu)造函數(shù)函數(shù)名和類名相同,無返回值,可以有參數(shù)
析構(gòu)函數(shù)在類名前加"~",無返回值,不能重載
拷貝構(gòu)造函數(shù):(用戶不拷貝構(gòu)造,系統(tǒng)調(diào)用默認(rèn)的拷貝構(gòu)造)
Date ob2 = ob1;(賦值使用默認(rèn)拷貝構(gòu)造)

自定義拷貝構(gòu)造函數(shù)后


應(yīng)用場(chǎng)景:


淺拷貝只復(fù)制指向某個(gè)對(duì)象的指針,而不復(fù)制對(duì)象本身,新舊對(duì)象還是共享同一塊內(nèi)存。(系統(tǒng)默認(rèn))
深拷貝會(huì)另外創(chuàng)造一個(gè)一模一樣的對(duì)象,新對(duì)象跟原對(duì)象不共享內(nèi)存,修改新對(duì)象不會(huì)改到原對(duì)象。(自定義)

13.初始化列表
對(duì)于有參構(gòu)造:
public:
Date (int a,int b, int c):m_a(a),m_b(b),m_c(c) //初始化成員列表
{
}
對(duì)于大類中對(duì)象成員的構(gòu)造可以使用初始化(比如class C中有class A 和class B的對(duì)象)

explicit禁止構(gòu)造函數(shù)隱式轉(zhuǎn)換

14.動(dòng)態(tài)對(duì)象創(chuàng)建


new和delete申請(qǐng)空間
//基本類型
int *p = NULL;
p = new int(100);
cout<<*p<<endl;
delete p;
//int 數(shù)組
int *arr = NULL;
arr = new int[5];
delete [] arr; //釋放數(shù)組格式
//字符串
char *arr = new char[32];
strcpy(arr,"helloworld"); 不能new char[32]{"helloworld"};
delete [] arr;
//給類對(duì)象申請(qǐng)空間
Person *p = new Person("lucy",100);
//由于p是指針
p->showPerson();
對(duì)象數(shù)組

初始化:人為調(diào)用構(gòu)造函數(shù)如下

new一下

PS:delete釋放*void指針沒有析構(gòu)
15.靜態(tài)成員變量
靜態(tài)成員屬于類

static int date;
int Person::date = 100; //類內(nèi)說明,類外定義
類名加作用域和對(duì)象名加點(diǎn)都可以訪問
static修飾靜態(tài)成員函數(shù)

靜態(tài)成員函數(shù)只能訪問靜態(tài)成員變量
const static int date;只讀不可改,用const修飾靜態(tài)成員
靜態(tài)成員變量可以統(tǒng)計(jì)對(duì)象個(gè)數(shù)

單例模式

15.this指針

等價(jià)于this -> m_num = num;
隱含指針,無需定義,靜態(tài)成員函數(shù)內(nèi)部沒有this指針
this和java中一樣有就近原則
用*this返回對(duì)象

PS:返回引用
16.const修飾成員函數(shù)

const修飾常對(duì)象
const Date ob1(200); //修飾+初始化
ob1.setDate(); //報(bào)錯(cuò)
常對(duì)象只能調(diào)用const修飾的函數(shù)(void setDate(int date)const{})不能改
17.友元(外部訪問私有成員)


還可以friend class Gay讓類中的成員函數(shù)都作為友元函數(shù)
例題:

數(shù)組類的強(qiáng)化
arry.cpp main.cpp arry.h
18.運(yùn)算符重載
operator關(guān)鍵字加運(yùn)算符實(shí)現(xiàn)運(yùn)算符重載

友元函數(shù)到類里

返回值為引用就可以迭代操作
ostream& operator<<(ostream &out,Person &ob){
out<<ob.name<<", "<<ob.num;
return out;
}
同理,"+"也可以

Person ob3 = ob1+ob2;//我打印不出來,思考1h沒理解

解決方法,刪掉自定義析構(gòu)
因?yàn)閐elete時(shí),目標(biāo)指針的指向中途發(fā)生了改變,導(dǎo)致錯(cuò)誤。



指針運(yùn)算符重載

設(shè)計(jì)一個(gè)智能指針能自動(dòng)釋放堆區(qū)空間

對(duì)于=號(hào),類中有指針才要重載運(yùn)算符

系統(tǒng)默認(rèn)淺拷貝(這里的等號(hào)并沒有人為重載過)


防止內(nèi)存泄漏
ob1 = ob2 = ob3 怎么重載呢?(從又往左迭代)
在operator前返回值改為對(duì)象引用類型即可
return *this //(ob)

Fun()是匿名對(duì)象 可以Fun()(100,200);




19.繼承和派生




如上是公共繼承
如下是保護(hù)繼承

私有繼承同理:

P105 用vs查看類的布局
關(guān)于構(gòu)造順序



從子類和父類同名的成員變量,在子類中默認(rèn)使用本作用域的,想用父類的加作用域

[虛繼承] (vs分析)
class 子類:virtual public 基類{};


20.多態(tài)


那我非要在用基類指針調(diào)用子類的sleep()呢?
c++提供了虛函數(shù)




虛析構(gòu)的作用

通過基類指針或引用釋放子類空間,在析構(gòu)函數(shù)前加virtual
純虛函數(shù)

抽象類不能實(shí)例化對(duì)象
抽象類作為接口


純虛析構(gòu)

重定義和重寫


21.函數(shù)模板



函數(shù)模板可以重載,普通函數(shù)類型是確定的 具體化
類模板
template<class T1,class T2>
class Date{};

類模板 派生 普通類

顯式調(diào)用父類有參構(gòu)造
關(guān)于類外定義

友元函數(shù)在模板中定義


22.c++的類型轉(zhuǎn)換
(1)靜態(tài)類型轉(zhuǎn)換(static_cast)

上行轉(zhuǎn)換
Aniaml *p = static_cast<Aniaml*>(new Dog);

(2)動(dòng)態(tài)轉(zhuǎn)換(dynamic_cast)

(3)常量轉(zhuǎn)換(const_cast)

(4)重新解釋轉(zhuǎn)換(reinterpret_cast)

23.C++異常拋出和捕獲

不捕獲直接退出
unwinding棧解旋:當(dāng)異常被拋出后,期間棧上構(gòu)造的所有對(duì)象都會(huì)被自動(dòng)析構(gòu)

異常的生命周期

拋地址(記得釋放)

匿名對(duì)象(常用)

標(biāo)準(zhǔn)異常

24.cin用法




STL(標(biāo)準(zhǔn)模板庫)





容器&迭代器使用


vs中for_each

容器里套容器(我套你猴子)

string



異常

字符串拼接

查找和替換

提取子串和插入

vector(容器)

它的迭代器跟普通指針一樣可以++~
capacity>=元素個(gè)數(shù)(size)
vector的未雨綢繆機(jī)制(另尋地址)


resize作用于大小,不作用于容量,除非resize比capacity大


數(shù)據(jù)存取操作
