精品網(wǎng)站建設(shè)平臺如何自己免費(fèi)制作網(wǎng)站
一、C++介紹
? ? 本賈尼.斯特勞斯特盧普,于1979年在貝爾實(shí)驗(yàn)室負(fù)責(zé)分析UNIX系統(tǒng)內(nèi)核流量的分布情況時,特別希望有一種更加模塊化的工具,于1979.10開始著手研發(fā)一款新的編程語言,在C語言的基礎(chǔ)上增加了面向?qū)ο蟮臋C(jī)制,也就是C++,1983年完成了C++的第一個版本
? ? C++與C的關(guān)聯(lián)和重要區(qū)別:
? ? 1、C++完全兼容C語言的所有內(nèi)容
? ? 2、支持面向?qū)ο蟮木幊趟枷?? ? ? //C是面對過程的
? ? 3、支持運(yùn)算符重載、函數(shù)重載的編譯時多態(tài)機(jī)制 //抽象(封裝) 繼承 多態(tài)
? ? 4、泛型編程、模版編程
? ? 5、支持異常處理
? ? 6、類型檢查更加嚴(yán)格
? ? 7、C++增加了名字空間的機(jī)制
二、第一個C++程序
?
#include <iostream>
using namespace std;int main(int argc,const char* argv[])
{cout << "Hello World!" << endl;return 0;
}
? ? 1、文件擴(kuò)展名由 .c 變成 .cpp ?.cc ?.C ?.cxx
? ? 2、編譯器由gcc變成g++,gcc也可以繼續(xù)使用,需要增加編譯參數(shù)
? ? ? ? -xC++ -lstdc++
? ? 3、C++語言的標(biāo)準(zhǔn)頭文件不帶.h,iostream意為in out stream,在C++中輸入、輸出被封裝成了流操作(數(shù)據(jù)流),C語言的頭文件還可以繼續(xù)使用,但是標(biāo)準(zhǔn)C的頭文件建議名字換成前面加c 后綴去掉的新名字 例如 cstdio,為了刪除原C標(biāo)準(zhǔn)頭文件中的大量的宏,重新放入名字空間中,防止命名沖突
? ? 4、C++輸入、輸出
? ? ? ? cout ? ?用于輸出
? ? ? ? cin ? ? 用于輸入
? ? ? ? 不需要占位符,會自動識別數(shù)據(jù)類型
? ? ? ? printf/scanf 屬于C標(biāo)準(zhǔn)庫中的函數(shù)
? ? ? ? cout/cin 是C++標(biāo)準(zhǔn)庫中的類對象 ?//不是函數(shù)
? ? 5、增加了名字空間機(jī)制,是C++為了解決命名沖突而發(fā)明的一項(xiàng)機(jī)制
三、C++與C數(shù)據(jù)類型的不同
? ? 1、結(jié)構(gòu)的不同
? ? ? ? a、不再需要通過typedef來縮短結(jié)構(gòu)類型名,在C++中設(shè)計(jì)好結(jié)構(gòu)后,定義結(jié)構(gòu)類型時不再需要使用struct關(guān)鍵字了
? ? ? ? b、結(jié)構(gòu)中可以有成員是成員函數(shù)、成員變量,結(jié)構(gòu)變量、結(jié)構(gòu)指針使用 . 和 -> 訪問成員,如果是成員函數(shù),那么可以直接訪問同結(jié)構(gòu)中的任何成員,不需要.和->
? ? ? ? c、結(jié)構(gòu)中有一些隱藏的成員函數(shù):構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造、賦值操作
? ? ? ? d、結(jié)構(gòu)可以繼承其它結(jié)構(gòu),也可以被其他結(jié)構(gòu)所繼承
? ? ? ? e、可以給成員賦予訪問控制屬性
? ? ? ? ? ? public ? ? ? ?公開的(默認(rèn))
? ? ? ? ? ? protected ? ? 保護(hù)的 ?結(jié)構(gòu)內(nèi)和繼承了它的結(jié)構(gòu)中能使用
? ? ? ? ? ? private ? ? ? 私有的 ?只有結(jié)構(gòu)中才能使用
? ?
? ? 2、聯(lián)合的不同
? ? ? ? a、不再需要通過typedef來縮短聯(lián)合類型名,在C++中設(shè)計(jì)好聯(lián)合后,定義聯(lián)合類型時不再需要使用union關(guān)鍵字了
? ? ? ? b、聯(lián)合中可以有成員是成員函數(shù)、成員變量,聯(lián)合變量、聯(lián)合指針使用 . 和 -> 訪問成員,如果是成員函數(shù),那么可以直接訪問同聯(lián)合中的任何成員,不需要.和->
? ? ? ? c、聯(lián)合中有一些隱藏的成員函數(shù):構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造、賦值操作
? ? ? ? d、可以給成員賦予訪問控制屬性
? ? ? ? ? ? public ? ? ? ?公開的(默認(rèn))
? ? ? ? ? ? protected ? ? 保護(hù)的 ?聯(lián)合內(nèi)和繼承了它的聯(lián)合中能使用
? ? ? ? ? ? private ? ? ? 私有的 ?只有聯(lián)合中才能使用
? ?
? ? 3、枚舉的不同
? ? ? ? a、不再需要通過typedef來縮短枚舉類型名,在C++中設(shè)計(jì)好枚舉后,定義枚舉類型時不再需要使用enum關(guān)鍵字了
? ? ? ? b、C++編譯器會對枚舉的值進(jìn)行檢查,如果不符合就報(bào)錯,只能給名字
? ? ? ? c、C語言使用整型來模擬的,C++中的枚舉類型是一種真正的數(shù)據(jù)類型,所以不能與整型進(jìn)行隱式類型轉(zhuǎn)換了
? ?
? ? 4、布爾類型的不同
? ? ? ? a、C++中有真正的布爾類型,bool、true、false 是C++的關(guān)鍵字,不再需要包含 stdbool.h 頭文件
? ? ? ? b、true、false 在C++中是1字節(jié),而C語言是4字節(jié)(int) ? //bool不是C語言的關(guān)鍵字 所以寫c需要導(dǎo)入頭文件
? ? ? ? 注意:無論C還是C++,bool類型變量只能存儲0|1
? ?
? ? 5、字符串的不同
? ? ? ? a、C++中的字符串被封裝成了 string 類,可以與C語言的字符串進(jìn)行轉(zhuǎn)換
? ? ? ? b、string類被封裝在 string 文件,并屬于std名字空間,但是string已經(jīng)被iostream包含
? ? ? ? c、使用string類,可以通過運(yùn)算符的方式直接操作字符串,但是C語言string.h中的str系列函數(shù)也可以繼續(xù)使用
? ? ? ? ? ? = ? strcpy
? ? ? ? ? ? += ?strcat
? ? ? ? ? ? == ?strcmp ?相同為真
? ? ? ? ? ? size() \ length() ?strlen 只算字符個數(shù)
? ? ? ? d、C++中沒有規(guī)定string類必須以'\0'結(jié)尾,編譯器在實(shí)現(xiàn)時可以在結(jié)尾加上'\0'也可以不加,由編譯器決定,因?yàn)閟tring是一個類,它的長度信息已經(jīng)被封裝記錄在私有成員變量中了
? ?
? ? 6、void*的不同?
? ? ? ? 在C語言中,void*類型可以與任意類型的指針進(jìn)行自動轉(zhuǎn)換
? ? ? ? 在C++中,void*類型不可以自動轉(zhuǎn)換成其他任意類型的指針,如果需要把void*類型的指針賦值給其他類型的指針時,必須通過強(qiáng)制類型轉(zhuǎn)換后才能賦值,為了提高指針數(shù)據(jù)類型的安全性
? ? ? ? 但是其他類型的指針還是可以自動轉(zhuǎn)換成void*類型的指針,因?yàn)镃語言標(biāo)準(zhǔn)庫、系統(tǒng)函數(shù)中采用了大量的void*類型作為參數(shù),如果不保留這個方式會導(dǎo)致C++在調(diào)用這些函數(shù)時非常麻煩
? ? ? ? ? ? int* p = (int*)malloc(4);
? ?
四、名字空間
? ? 1、為什么需要名字空間
? ? ? ? 由于C++完全兼容C語言,C++標(biāo)準(zhǔn)庫中自帶大量的類、函數(shù)、宏,而且支持繼承語法,導(dǎo)致全局的標(biāo)識符大量增加,因此命名沖突的概率極大的增加,因此名字空間就是為了解決命名沖突
? ? 2、什么是名字空間
? ? ? ? 是C++中一種對命名空間進(jìn)行邏輯劃分的一種技術(shù)?
? ? ? ? namespace xxx
? ? ? ? {
? ? ? ? ? ? 變量;
? ? ? ? ? ? 函數(shù);
? ? ? ? ? ? 結(jié)構(gòu)、聯(lián)合、枚舉;
? ? ? ? ? ? 類;
? ? ? ? ? ? ...
? ? ? ? }??
? ? ? ? 定義了名字空間后形成了一個相對封閉的作用域空間
? ? 3、如何使用
? ? ? ? 1、直接導(dǎo)入
? ? ? ? ? ? using namespace xxx;
? ? ? ? ? ? 之后就可以直接使用名字空間中的所有內(nèi)容,雖然方便,實(shí)際工作中不建議
? ? ? ? 2、域限定符 ::
? ? ? ? ? ? xxx::標(biāo)識符
? ? 4、名字空間可合并
? ? ? ? 名字空間可以被多次定義,不同位置的名字空間編譯器會在編譯時自動合并
? ? ? ? a.cpp
? ? ? ? namespace n1{int a;}
? ? ? ? b.cpp
? ? ? ? namespace n1{int b;}
? ? ? ? main.cpp
? ? ? ? using namespace n1;// ?會把a(bǔ)、b都導(dǎo)入進(jìn)來
? ? 5、名字空間中的聲明和定義可以分開
? ? ? ? a.h
? ? ? ? namespace n1{
? ? ? ? ? ? extern int num;
? ? ? ? }
? ? ? ? a.cpp
? ? ? ? int n1::num;
? ? ? ? 注意:可以分開定義,但是必須加上 名字空間名::變量名
? ? 6、匿名名字空間
? ? ? ? 所有全局標(biāo)識符都?xì)w屬于同一個名字空間,稱為匿名名字空間,可以通過 ::全局標(biāo)識符 來指定訪問匿名名字空間中的內(nèi)容
? ? ? ? 例如:同名的全局變量被同名局部變量屏蔽后,可以以此指定訪問全局變量
? ? 7、名字空間可以嵌套
? ? ? ?
namespace n1{int num = 10;namespace n2{int num = 20;namespace n3{int num = 30; ?}} ?}
? ? ? ? 采用逐層分解訪問
? ? ? ? n1::n2::n3::num
? ? ? ? 導(dǎo)入指定層的名字空間
? ? ? ? using namespace n1::n2;
? ? 8、可以給名字空間的名字取別名
? ? ? ? namespace n123 = n1::n2::n3
五、C++的堆內(nèi)存管理
? ? 1、語法格式:
? ? ? ? 類型* p = new 類型名;
? ? ? ? ? ? new 分配內(nèi)存,相當(dāng)于C語言的malloc ?
? ? ? ? delete p; ?
? ? ? ? ? ? delete 釋放內(nèi)存 相當(dāng)于C語言的free(p)
? ? 2、new 允許在分配內(nèi)存時直接初始化內(nèi)存
? ? ? ? 類型* p = new 類型名(val);
? ? ? ? int* p = new int(10);
? ?
? ? 3、new/delete 不能與 malloc/free 混合使用
? ? ? ? int* p = new int;
? ? ? ? free(p);
? ? ? ? 雖然語法允許,但是不能這樣混合使用
? ? ? ? 因?yàn)槭褂胣ew分配內(nèi)存時,會自動調(diào)用結(jié)構(gòu)、聯(lián)合、類類型的構(gòu)造函數(shù),使用delete釋放內(nèi)存時,會自動調(diào)用結(jié)構(gòu)、聯(lián)合、類類型的析構(gòu)函數(shù)
? ? ? ? 但是malloc和free都不會調(diào)用,如果混用,就會導(dǎo)致構(gòu)造、析構(gòu)沒有對應(yīng)調(diào)用
? ? 4、連續(xù)內(nèi)存的申請和釋放
? ? ? ? 類型* p = new 類型名[個數(shù)];
? ? ? ? ? ? int* p = new int[10];//10個int類型的連續(xù)堆內(nèi)存40字節(jié)
? ? ? ? ? ? new[] 會多次調(diào)用構(gòu)造函數(shù)
? ? ? ? delete[] p;
? ? ? ? ? ? delete[]專門用于釋放通過 new[] 申請出來的內(nèi)存
? ? ? ? ? ? delete[]也會多次調(diào)用析構(gòu)函數(shù)
? ? ? ? 注意:malloc/free ?new/delete ?new[]/delete[] 都不能混用
? ? ? ? 注意:通過new[]為結(jié)構(gòu)、聯(lián)合、類類型申請的內(nèi)存的前4字節(jié)[-1]中記錄了申請的次數(shù),這樣就可以讓編譯器知道需要調(diào)用多少次構(gòu)造函數(shù)和析構(gòu)函數(shù)
? ? 5、重復(fù)釋放問題
? ? ? ? delete可以釋放空指針,但是也不能重復(fù)釋放其他有效地址,與free一致
? ? 6、內(nèi)存分配失敗?
? ? ? ? malloc分配內(nèi)存失敗會返回NULL
? ? ? ? new分配內(nèi)存失敗會拋出一個異常std::bad_array_new_length,如果不接異常并處理,那么會終止
? ? 7、返回值類型不同
? ? ? ? malloc返回一個void*類型的指針
? ? ? ? new返回一個對應(yīng)類型的指針
? ? ? ? ? ? ? ? ? ? malloc/free ? 和 ? new/delete 的區(qū)別?
? ? 身份(本質(zhì)): ?????????函數(shù) ? ? ? ? ? ? ? ? ????????????????關(guān)鍵字/運(yùn)算符
? ? 返回值:? ? ? ? ? ? ? ? void* ? ? ? ? ? ? ? ?????????????????對應(yīng)類型的指針
? ? 參數(shù):? ? ? ? ? ? ? ? ? ?字節(jié)個數(shù)(手動計(jì)算)? ? ? ? ? 類型(自動計(jì)算字節(jié)個數(shù))
? ? 連續(xù)內(nèi)存:? ? ? ? ? ? 手動計(jì)算總字節(jié)數(shù)? ? ? ? ? ? new[個數(shù)]
? ? 擴(kuò)容: ? ? ? ????????? ? ?realloc ? ? ? ? ? ? ?????????????????無法直接處理
? ? 失敗:? ? ? ? ? ? ? ? ? ? 返回NULL? ? ? ? ? ? ? ? ? ? ? ? 拋異常
? ? 構(gòu)造\析構(gòu):? ? ???????不調(diào)用 ? ? ? ? ? ? ? ???????????????調(diào)用
? ? 初始化:? ? ? ? ? ? ? ?不能初始化 ? ? ? ? ?????????? ? ? 可以初始化
? ? 頭文件: ? ? ????????? ?stdlib.h ? ? ? ? ? ? ????????????????不需要
? ? 函數(shù)重載: ? ?????????不允許重載 ? ? ? ?????????? ? ? ? 允許
? ? 內(nèi)存分配的位置:? 堆內(nèi)存 ? ? ? ? ? ? ?????????????????自由存儲區(qū)
? ? ? ? 注意:自由存儲區(qū)是一個抽象的概念,而不是具體某個位置段,平時一般稱new是分配在堆內(nèi)存也問題不大,因?yàn)閚ew底層默認(rèn)調(diào)用了malloc,所以此時稱分配在堆內(nèi)存沒問題,但是new可以像運(yùn)算符一樣被程序員重載或借助 new(地址) 類型 兩種方式分配內(nèi)存時,可以分配到其他內(nèi)存段,所以稱為自由存儲區(qū)