c++ 知識點整理

Section 1

命名空間

  • 三種方式
using std::cout;//全部文件使用的cout來自std

std::cout << "hello" << std::endl;//用的地方指定

using namespace std;//把std所有的命名空間全部引入
  • 定義一個命名空間
    在這裏插入圖片描述
  • 07 using聲明和using編譯指令
    在這裏插入圖片描述

對C語言增強的地方

  • 在c++中,變量可以隨用,隨定義;C一般要求定義在前面;
  • c中對全局變量重複定義,會解釋爲一個是聲明;c++會報錯
    在這裏插入圖片描述
  • struct student在c中定義變量要加上struct;在c++中不用(把他當成類處理)直接student s1
    在這裏插入圖片描述
  • 對於函數在c中不寫返回值(默認是int),不會報錯;c++強制要寫
  • 在c中可以傳多餘的參數
  • 增加了bool類型
  • 三目運算符在c++中可以當左值:返回的值變量的引用
    在這裏插入圖片描述
  • const的增強:針對直接賦值(通過指針,全局變量都不能改,局部變量c可以改,c++改的是臨時變量的值,本身沒有改)
    • 對const修飾的變量取地址的時候,會分配臨時內存(一般來說分配了內存就可以通過指針改,但是這個臨時的內存改了沒有意義)

    • const前加入關鍵字external後也會分配內存,(這裏通過指針改會報錯)

    • 使用變量初始化const的變量可以通過指針修改在這裏插入圖片描述

    • 自定義的數據類型也可以通過指針修改 在這裏插入圖片描述

    • c中的const可以改(針對直接賦值)
      在這裏插入圖片描述

    • 在這裏插入圖片描述

    • 編譯器看到a就會到文字常量區的符號表找到key值爲a的value替代,類似於宏定義,不同的是宏定義是在預處理階段,const處理是在編譯階段

    • 在這裏插入圖片描述
      在這裏插入圖片描述

    • 枚舉的增強:c中可以用int表示(含義不清)

引用的基本語法

  • int &是引用的數據類型,就是別名;
    在這裏插入圖片描述

  • 通過引用,在函數傳參的時候可以用引用做形參接收,迴避了傳指針的麻煩;
    在這裏插入圖片描述

  • 引用的本質:int *const p(常指針,內容可變,p值不變)

  • 引用一定要定義的時候初始化,跟const一樣

  • 引用的大小和指針一樣

  • int *const p=&a
    在這裏插入圖片描述
    在這裏插入圖片描述

  • 有關常指針:數組爲例
    在這裏插入圖片描述

  • 引用作爲函數的返回值:

  • 引用作爲返回值,不要返回局部變量的引用

  • 如果是在堆上開闢的,或者是static定義的局部變量可以返回

  • 函數可以作爲左值(如果函數返回值是指針,他也是返回的是數值,不能作爲左值,但是引用可以)

  • 在這裏插入圖片描述

  • 指針引用

    • 避免了二級指針操作中容易出錯
      在這裏插入圖片描述
  • const 修飾引用(可以通過指針修改)
    在這裏插入圖片描述

    • 引用用在形參上(可以不用開闢新的空間),但是爲了防止誤操作改變外面的量,可以加上const:
      在這裏插入圖片描述

內聯函數

  • 如果反覆多次調用一個函數,就會有多次進出棧的操作,爲了避免這個開銷。引入內聯函數
  • 內聯函數的作用類似於宏函數(但是宏函數不會檢查語法錯誤。,是在預處理階段做的,沒有語法檢查的能力)
  • 內聯函數是編譯階段做的,有語法的檢查能力,本質就是在調用處,原處展開。(但是不會無限展開,如果代碼量太大,爲了避免過於佔用內存,還是會進出棧操作,比如在inline里加個1000次的循環),一般用在一兩行代碼,要反覆運行的位置(犧牲空間換時間)
  • 成員函數一般都很短,他們都隱藏了關鍵字inline
    在這裏插入圖片描述

進入18

函數的默認參數以及佔位參數

  • 帶默認參數
    在這裏插入圖片描述
  • 函數的聲明和實現只能有一個有默認參數
  • 函數的佔位參數:符號重載用
    在這裏插入圖片描述
  • 函數重載(不是複寫)
    在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

  • 原理:編譯器針對不同的函數,修改了函數名

externC

  • 因爲c++獨有的函數重載機制,編譯器會修改函數名(方便找到函數),所以在c++編譯器上運行c++代碼要加上一下帶條件宏定義:
    在這裏插入圖片描述

c語言的結構體不做類型的檢測,完全只是內存大小相同即可,只是檢測指針的步長。導致不同的結構體,只要內存分配相同,可以同樣傳遞:

  • 例如一個函數要求傳入的結構他爲person但是另一個結構體dog內存分配與人相同也可以傳入該函數。
  • c語言中結構體裏只能放屬性,不能放行爲(函數,要函數指針纔行)

c++中struct和class區別就是默認權限不同,struct默認public,class默認private(class相比struct增加了權限控制)

Section 2

類相關

構造函數和析構函數

  • 編譯器自動調用

  • 編譯器自動生成空的無參構造和析構

  • 在公共作用域下

  • 構造:沒有返回值,也不用寫void,跟類名寫法一樣,可以重載

  • 析構:函數名前加~

  • 拷貝構造函數(就是拷貝一個對象):傳的是同類對象的引用,防止修改要加const

    • 要用&接收,不用的話就是值傳遞。要新創建對象,就進入了無限的循環
      在這裏插入圖片描述
  • 調用:

    • 括號法:
      在這裏插入圖片描述
    • 顯示法:
      在這裏插入圖片描述
    • 注意點:
      在這裏插入圖片描述
    • 隱式法:
      在這裏插入圖片描述
  • 拷貝構造函數的調用時機

    • 當傳值的時候,形參就是調用 了拷貝構造函數:Person p=p1(隱式法)
      在這裏插入圖片描述
    • 以值的方式返回局部對象
      在這裏插入圖片描述
  • 構造函數的調用規則
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述

深拷貝與淺拷貝

  • 淺拷貝的時候只拷貝了指針,這樣在釋放的時候,其他有拷貝構造函數創建出來的對象p2先釋放了指針,而本對象p1再釋放就會崩潰;解決方法就是深拷貝:

在這裏插入圖片描述

  • 重寫系統默認的拷貝構造函數(系統只會簡單的值拷貝):
    在這裏插入圖片描述

初始化列表

  • 用來初始化屬性
    在這裏插入圖片描述
    在這裏插入圖片描述
  • explicit關鍵字使用
    在這裏插入圖片描述
  • new和delete運算符:完成了開闢空間,調用構造函數(賦值),判斷的複合工作
    • new
      在這裏插入圖片描述
      在這裏插入圖片描述
      區別
      在這裏插入圖片描述
    • 注意事項:
      在這裏插入圖片描述
    • 利用new創建數組
      在這裏插入圖片描述

靜態成員

  • 爲什麼要在類外初始化:

    • 因爲如果沒有創建對象,類裏面的代碼不會運行;
    • 編譯期(分配了空間)
    • 這個時候如果用類名訪問就會報錯(沒有值)
    • 但是私有的靜態成員,可以不用賦值,類外通過類名也訪問不到,但是可以在類外賦值
  • 在這裏插入圖片描述

  • 訪問方式
    在這裏插入圖片描述

  • 單例模式:

    • 私有有參構造和拷貝構造
    • 加了作用域:可以視爲是在類內部執行的,所以能訪問私有構造; 在這裏插入圖片描述

C++對象模型初探-成員變量和成員函數分開存儲

  • 在這裏插入圖片描述

this指向被調用成員函數所屬的對象

  • 編譯器編譯的時候,把this指針已經加入了:
    在這裏插入圖片描述
    在這裏插入圖片描述- 空指針訪問成員函數
    • 也可以訪問沒用用到this 的成員函數;否則會崩潰

常函數和常對象

在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

  • 加上關鍵字mutable
    在這裏插入圖片描述
  • 常對象
    在這裏插入圖片描述
    • 常對象不能調用普通的成員函數,只能調用常函數。

友元

  • 全局函數作爲友元函數

    • 在類中用friend關鍵字+全局函數的聲明,就能訪問該類內部的私有屬性
      在這裏插入圖片描述
  • 友元類

    • 友元類不一定有傳遞性,可逆性
    • 類內的函數,可以放在類外部實現,加上命名空間就行
      在這裏插入圖片描述
      同樣:在這裏插入圖片描述
  • 同理也可以是指成員函數,作爲另一個類的友元;

數組類封裝

運算符重載

  • 加運算符:分別利用成員函數,和全局函數

  • 在這裏插入圖片描述
    在這裏插入圖片描述

  • 左移運算符重載

    • 要用全局函數實現
      在這裏插入圖片描述
    • 返回引用是爲了鏈式編程 在這裏插入圖片描述
  • 遞增運算符重載++

  • 前置++:一般放在成員函數,考慮到一直要操作,所以要返回引用,例如:++(++a)
    -在這裏插入圖片描述 - 後置++:返回的是臨時變量,本體內部已經記錄了;臨時變量方法調用完會回收,所以不能返回引用;
    在這裏插入圖片描述

  • 由於後置++產生了臨時副本,所以爲了效率考慮,推薦日常使用前置++;
    在這裏插入圖片描述

  • 指針運算符重載-智能指針
    在這裏插入圖片描述

  • 賦值運算符重載
    在這裏插入圖片描述

  • []運算符重載

  • 關係運算符重載

  • 函數調用運算符重載

  • 不要重載邏輯與和邏輯或符號:因爲沒法實現短路的效果
    在這裏插入圖片描述

Section 3

繼承和派生

  • 語法:class 子類:繼承方式:父類
  • 繼承方式
    在這裏插入圖片描述
    • protected 子類可以訪問,其他地方不可訪問
    • private 只有自己類可以訪問

繼承中的對象模型

在這裏插入圖片描述
在這裏插入圖片描述

繼承中的構造和析構

  • 在這裏插入圖片描述

  • 子類默認走父類的無參構造,但是可以利用初始化列表指定要走的父類構造函數(類似於java中的super):
    在這裏插入圖片描述

  • 子類不繼承父類的構造函數和析構函數,只有父類才知道怎麼樣構造和析構自己的屬性

  • 繼承中的同名成員處理

  • 在這裏插入圖片描述

  • 繼承中的同名靜態成員處理
    在這裏插入圖片描述
    在這裏插入圖片描述

  • 多繼承的語法
    在這裏插入圖片描述

  • 菱形繼承問題以及解決

  • 使用虛繼承處理兩份數據的問題(二義性,浪費內存)
    在這裏插入圖片描述
    在這裏插入圖片描述

  • 虛繼承的內部工作原理剖析

    • 一旦使用了虛繼承,那麼內部之前綁定的變量就會變成指針,指向一個表,表中的內容就會根據子類是否重寫而覆蓋

多態相關

-動態聯編,通過虛函數實現-
在這裏插入圖片描述
在這裏插入圖片描述

  • 多態原理
    在這裏插入圖片描述
  • 多態的好處(計算器案例)
    • 把要幹什麼和怎麼幹分開
    • 在這裏插入圖片描述
  • 純虛函數的類,也叫抽象類
    • 純虛函數子類一定要重寫
    • 純虛函數跟java的抽象函數類似;
    • 在這裏插入圖片描述
  • 虛析構和純虛析構
  • 虛析構:當子類有的屬性是創建在堆區上的,那麼就要重寫析構函數,爲了子類delete的時候能夠調用到,父類的析構函數應該寫成虛析構;
  • 純虛析構和純虛函數不同:由於父類的析構函數一定會被調用(父類自己也有屬性可能在堆區,自己也要釋放),所以要有函數體;但是純虛函數已經=0,所以函數體寫在外面;
    在這裏插入圖片描述
  • 純虛析構 有了之後,也變成了抽象類;
    在這裏插入圖片描述
  • 向上向下類型轉換
    在這裏插入圖片描述
    在這裏插入圖片描述
  • 重寫、重載、重定義;
    • 重定義: 在這裏插入圖片描述在這裏插入圖片描述

泛型編程

模板技術

在這裏插入圖片描述

  • 引用傳遞的時候原名的類型和別名的類型一定要一致,編譯器不會自己幫你轉(例如char 轉 int),但是普通的傳遞會轉
    在這裏插入圖片描述
  • 模板使用:編譯器推導出來了也行;推不出來就要指定(比如:函數都沒有參數的時候)

在這裏插入圖片描述

  • 函數模板和普通函數的區別以及調用規則
    • 區別:
      在這裏插入圖片描述
      -規則:
      在這裏插入圖片描述
      在這裏插入圖片描述
      在這裏插入圖片描述
  • 模板機制
    在這裏插入圖片描述
    • 函數模板通過傳入的T的類型生成了模板函數(編譯器內部生成的)
      在這裏插入圖片描述
    • 模板的侷限性以及解決:不能真的針對每一個類型
      在這裏插入圖片描述
      在這裏插入圖片描述
類模板
  • 與函數模板的區別:

    • 類模板不能使用自動類型推導,必須顯示指定
    • 類模板中的類型可以有默認參數(默認什麼類),函數模板不行;
  • 泛型編程:體現在模板技術;特點是將類型參數化;

  • 類模板中的成員函數創建時機

    • 類模板的成員函數,並不是一開始就創建出來的,而是在運行階段,傳入了T的具體類型才創建出來的;
  • 類模板作爲函數參數 在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述
    在這裏插入圖片描述

  • 類模板碰到繼承的問題以及解決

    • 子類創建的時候必須要知道父類模板T是什麼類型,否則無法給父類分配內存(因爲要走子類父類的構造)
    • 如果子類是具體類(不是類模板),那就指定父類T的類型
      在這裏插入圖片描述
    • 如果子類是類模板,那麼把自己的一個泛型交給父類就行:
      在這裏插入圖片描述
  • 類模板的類外實現
    在這裏插入圖片描述

  • 類模板的分文件編寫問題以及解決
    在這裏插入圖片描述

  • 類模板碰到友元函數
    在這裏插入圖片描述

    在這裏插入圖片描述

  • 類模板案例—數組類封裝

    • 需要注意的是,自定義對象的數組初始化前,會先初始化自定義對象(走無參的默認構造0),自定義類裏的有參構造會默認刪掉無參構造(所以自己手動補上)
      在這裏插入圖片描述

類型轉換-靜態類型和動態類型轉換

在這裏插入圖片描述
- 自定義類型 支持繼承類對象的,指針,引用間的轉換;
- 沒有繼承關係的不支持

  • 動態轉換(嚴謹)

    • 不安全或者丟失精度都不讓轉
      在這裏插入圖片描述
  • 類型轉換-常量類型

    • 不允許把非指針或者非引用做const_cast轉換(不能把常量轉成變量)
      在這裏插入圖片描述
  • 重新解釋類型轉換(不安全,不建議用)
    在這裏插入圖片描述
    在這裏插入圖片描述

Section 4

  • 異常的基本語法

    • 爲什麼要有異常:c中的返回值判斷有缺陷(可能是異常,也可能是正常值) 在這裏插入圖片描述
      在這裏插入圖片描述
  • 拋出自定義異常:跟java不一樣,不用繼承exception的父類

  • 棧解旋 在這裏插入圖片描述

  • 異常的接口聲明 在這裏插入圖片描述
    在這裏插入圖片描述

  • 異常變量的生命週期

    • 值的方式接受對象,會調用拷貝構造
      在這裏插入圖片描述
    • 用引用接受
      在這裏插入圖片描述
  • 用指針接收,匿名對象走完本行沒有變量接收就會回收,指針就變成野指針(接收匿名對象的地址沒有用)
    在這裏插入圖片描述

  • 異常變量如果拋出有接收的話,在拋出的函數體內創建的對象不會釋放(即使是創建在棧上,創建在堆上的更不會),他的生命週期跑到了catch的函數體裏;不像函數返回值(會在本函數結束的時候釋放棧裏的內容),理解:一個拋字,拋出去了就不規我管了。
    在這裏插入圖片描述

  • 異常的多態使用

    • 繼承基類異常,由基類異常的引用接受
      在這裏插入圖片描述
  • 使用C++系統標準異常類

  • 編寫自己的異常類(繼承系統的)

    • char* 不可以直接賦值給string,要通過構造函數string(char*)
      在這裏插入圖片描述
      在這裏插入圖片描述
      在這裏插入圖片描述
  • 標準輸入流
    在這裏插入圖片描述

  • 理解:cin就是鍵盤的緩衝區(輸入的數據現在緩衝區,cin.get就是在這個緩衝區拿);同理cout也有緩衝區,endl會刷新緩衝區,並加上\n換行符;

    在這裏插入圖片描述
    在這裏插入圖片描述

  • 標準輸出流

  • 格式化輸出(成員函數法)
    在這裏插入圖片描述

    • 控制符法:
      在這裏插入圖片描述
  • 文件的讀寫

    • 寫:
      在這裏插入圖片描述

    • 在這裏插入圖片描述
      在這裏插入圖片描述
      在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章