C/C++基础知识点(一)
文章目錄
- 1.static關鍵字的作用
- 2.C++中的類型轉換符
- 3.指針和引用的區別
- 4.C++中的智能指針
- 5.數組與指針的區別
- 6.野指針是什么
- 7.為什么父類的構函數必須是虛函數,C++默認析構函數不是虛函數?
- 8.函數指針
- 9.靜態函數和虛函數的區別
- 10.重載和覆蓋區別
- 11. ++i和i++的實現
- 12.寫個函數在main函數執行前先運行
1.static關鍵字的作用
- 全局靜態變量:在全局變量前加上關鍵字static,就定義成一個全局靜態變量。作用域:全局靜態變量在聲明它的文件之外是不可見的。
- 局部靜態變量:在局部變量之前加上static,局部變量就變成局部靜態變量。作用域:作用域仍為局部作用域,當定義它的函數或者語句塊結束的時候,作用域結束。但是當局部靜態變量離開作用域后,不會銷毀,會一直在內存中,只不過不能再進行訪問,直到該函數再次被調用,并且值不會變。
- 靜態函數:在函數返回類型前加上static關鍵字,函數就變成靜態函數,函數的定義和聲明在默認情況下都是extern的,但靜態函數只是在聲明它的文件中可見,不能被其他文件所用。
函數的實現使用static修飾,這個函數只能在本cpp中使用,不會同其他cpp中的同名函數沖突。 - 類的靜態成員:在類中,靜態成員可以實現多個對象之間的數據共享,并且使用靜態數據成員還不會破壞隱藏的原則,即保證了安全性。因此,靜態成員是類的所有對象中共享的成員,而不是某個對象的成員。
- 類的靜態函數:它屬于類而不是屬于對象,在靜態成員函數的實現中不能直接引用類中說明的非靜態成員,可以引用類中說明的靜態成員。如果靜態成員函數中要引用非靜態成員時,可通過對象來引用(通過參數傳遞的方式得到對象名,然后再通過對象名引用)。
2.C++中的類型轉換符
- const_cast:用于將const變量轉換成非const
- static_cast:用于各種隱式轉換,比如非const轉const,void*轉指針等,static_cast能用于多態向上轉化,如果向下轉能成功但是不安全,結果未知。
- dynamic_cast:用于動態類型轉換。只能用不含有虛函數的類,用于類層次間的向上和向下轉化,只能轉指針或引用。向下轉換時,如果是非法的 對于指針 返回NULL,對于引用拋異常。
向上轉換:指的是子類向基類轉換
向下轉換:指的是基類向子類轉換
它通過判斷在執行到該語句的時候變量的運行是類型和要轉換的類型是否相同來判斷是否能夠進行向下轉換。 - reinterpret_cast:幾乎什么都能轉,比如int轉指針,可能會出問題,盡量少用。
關于C++的類型轉換詳細介紹參考這里
3.指針和引用的區別
- 指針有自己的一塊空間,而引用只是一個別名
- 指針的大小是4,引用則是被引用對象的大小
- 指針可以被初始化為NULL,而引用必須被初始化且必須是一個已有對象的引用
- 作為參數傳遞時,指針需要被解引用才可以對對象進行操作,而直接對應用的修改都會改變引用所指向的對象
- 可以有const指針,但沒有const引用
- 指針在使用中可以指向其他對象,但是引用只能是一個對象的引用,不能被改變
- 指針可以有多級指針(**p),而引用只有一級
- 指針和引用使用++運算符的意義不一樣
- 如果返回動態內存分配的對象或者內存,必須使用指針,引用可能引起內存泄漏。
4.C++中的智能指針
C++里面有四個智能指針:auto_ptr、shared_ptr、weak_ptr、unique_ptr,其中后三個是C++11支持,第一個已經被C++11棄用。
為什么要使用智能指針?
智能指針的作用是管理一個指針,因為存在以下這種情況:申請的空間在函數結束時忘記釋放,造成內存泄漏。使用智能指針可以避免這種問題,因為智能指針就是一個類,當超出這個類的作用域后,類會自動調用析構函數,析構函數自動釋放資源。
- auto_ptr(C++98方案,C++11已經棄用)采用所有權模式。
此時不會報錯,p2剝奪了p1的所有權,但是當程序運行時訪問p1將會報錯。所以auto_ptr的缺點是:存在潛在的內存崩潰問題。
- unique_ptr: 替換auto_ptr,unique_ptr實現獨占式擁有或嚴格擁有概念,保證同一時間內只有一個智能指針可以指向該對象。它對于避免資源泄漏特別有用。
編譯器認為p4=p3非法,避免了p3不再指向有效數據的問題。因此unique_ptr比auto_ptr更安全。
-
shared_ptr:共享式擁有概念。多個智能指針可以指向相同對象,該對象和其相關資源會在“最后一個引用被銷毀”的時候釋放。從名字shared就可以看出了資源可以被多個指針共享。可以通過use_count()來查看資源的所有者個數。
-
weak_ptr: 是一中不控制對象生命周期的智能指針,它指向一個shared_ptr管理的對象,weak_ptr設計的目的是為了配合shared_ptr而引入的一種智能指針來協助它工作的,解決shared_ptr相互引用時的死鎖問題。如果兩個shared_ptr相互引用,那么這兩個指針的引用計數永遠不可能為0,資源不會釋放。
5.數組與指針的區別
- 指針保存數據的地址,數據保存數據
- 指針間接訪問數據,首先獲得指針的內容,然后將其作為地址,從該地址中提取數據,而數組是直接訪問數據
- 指針通常用于動態的數據結構,數組通常用于固定數目且數據類型相同的類型
- 指針通過malloc或new分配內存,free或delete釋放內存,數組隱式分配和刪除
- 指針通常指向匿名數據,操作匿名函數,數組自身即為數據名
6.野指針是什么
野指針就是指向一個已刪除的對象或者未申請訪問受限內存區域的指針。
7.為什么父類的構函數必須是虛函數,C++默認析構函數不是虛函數?
將可能會被繼承的父類的析構函數設置為虛函數,可以保證在釋放基類指針時可以釋放掉子類的空間,防止內存泄漏。
C++默認的析構函數不是虛函數是因為虛函數需要額外的虛函數表和虛表指針,占用額外的內存。而對于不會被繼承的類來說,其虛析構函數會浪費內存。所以默認的析構函數不是虛函數。
8.函數指針
- 定義:函數指針是指向函數的指針變量。函數指針本身是一個指針變量,該指針變量指向一個具體的函數。這正如用指針變量可以指向整型變量、字符型、數組一樣,這里指向函數。
C在編譯時,每個函數讀由一個入口地址,該入口地址就是函數指針所指向的地址。有了該指針變量后,可用來調用其函數,就如同用指針變量可引用其他類型變量一樣。 - 用途:調用函數和做函數的參數,比如回調函數。
- 示例:
9.靜態函數和虛函數的區別
靜態函數在編譯的時候就已經確定運行時機,虛函數在運行的時候動態綁定。虛函數因為用了虛函數表機制,調用的時候會增加一次內存開銷。
虛函數的實現:在有虛函數的類中,類的最開始部分是一個虛函數表的指針,這個指針指向一個虛函數表,表中存放了虛函數的地址,實際的虛函數在代碼段中。當子類繼承了父類會同時繼承其虛函數表,子類在重寫父類中的虛函數時,會更新虛函數表中的地址為重寫的函數地址。使用虛函數,會增加訪問開銷,降低效率。
10.重載和覆蓋區別
- 重載:兩個函數名稱相同,但是參數列表不同,返回類型沒有要求,在同一作用域中。
- 重寫:子類繼承父類,父類中的函數是虛函數,在子類中重新定義了這個虛函數,并重寫函數體。
11. ++i和i++的實現
++i的實現
int & int::operator++() {*this += 1;return *this; }i++的實現
const int int::operator(int) {int oldValue = *this;++(*this);return oldValue; }12.寫個函數在main函數執行前先運行
__attribute((constructor))void before() {printf("before main\n"); }總結
以上是生活随笔為你收集整理的C/C++基础知识点(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MQTT连接阿里云IoT(四)
- 下一篇: C/C++基础知识点(二)