C++面試題目彙總

1、說一下static關鍵字的做用c++

1.全局靜態變量編程

在全局靜態變量前加上關鍵字static,全局變量就定義爲一個全局靜態變量安全

內存中的位置:靜態存儲區,在整個程序運行期間一直存在函數

初始化:未經初始化的全局靜態變量會被自動初始化爲0,(自動對象的值是任意的,除非他被顯示初始化)spa

做用域:全局靜態變量在聲明他的文件以外是不可見的,準確的說是從定義之處開始,到文件結束設計

2.局部靜態變量指針

在局部變量以前加上static,局部變量變成局部靜態變量code

內存中的位置:靜態存儲區對象

初始化:未經初始化的全局靜態變量會被自動初始化爲0,(自動對象的值是任意的,除非他被顯示初始化)blog

做用域:做用域仍爲局部做用域,當定義它的函數或者語句塊結束的時候,做用域結束,當時當局部靜態變量離開做用域後,並無銷燬,而是仍然駐留在內存當中,只是咱們不能在對他進行訪問,直到該函數被再次調用,而且值不變。

3.靜態函數

在函數返回類型前加static,函數就定義爲靜態函數。函數的定義和聲明在默認狀況下都是extern,但靜態函數只在聲明他的文件中可見,不能被其餘文件引用。

函數的實現使用static修飾,那麼這個函數只可在本cpp中使用,不會同其餘cpp中的同名函數引發衝突

warning:不要在頭文件中聲明static的全局函數,不要在cpp內聲明非static的全局函數,若是要在多個cpp中複用該函數,就把他的聲明提到頭文件裏面去,不然cpp內部聲明須要加上static修飾

4.類的靜態成員

在類中,靜態成員變量能夠實現多個對象之間的數據共享,而且使用靜態數據成員還不會破壞隱藏的原則,保證了安全性。靜態成員是類中全部對象共享的成員,而不是某個對象的成員。對多個對象來講,靜態成員只是存儲一處,供全部對象使用。

5.類的靜態函數

靜態成員函數和靜態數據成員同樣,它們都屬於類的靜態成員,它們都不是對象成員。所以,對靜態成員的引用不須要用對象名。

在靜態成員函數的實現中不能直接引用類中說明的非靜態成員,能夠引用類中說明的靜態成員(這點很是重要)。若是靜態成員函數中要引用非靜態成員時,可經過對象來引用。從中可看出,調用靜態成員函數使用以下格式:<類名>::<靜態成員函數名>(<參數表>);
2、說一次C++和C的區別
設計思想上:
C++是面向對象的語言,而C是面向過程的
語法上:
C++具備封裝繼承多態三種特性
C++相比C,增長了許多類型安全的功能,好比強制類型轉換
C++支持範式編程,好比模板類、函數模板等
3、說一下C/C++中指針和引用的區別
1.指針擁有本身的一塊空間,而引用只是一個別名
2.使用sizeof看一個指針的大小是4個字節,而引用則是被引用對象的大小
3.指針能夠被初始化爲NULL,而引用必須被初始化且必須是一個已有對象的引用
4.做爲參數傳遞時,指針須要被解引用才能夠對對象進行操做,而直接對引用的修改都會改變引用所對應的對象
5.能夠有const指針,不能夠有const引用
6.指針在使用中能夠指向其餘對象,可是引用只能是一個對象的引用,不能被改變
7,指針能夠有多級指針,而引用只有一級
8.指針和引用對++自增運算符的意義不同
9.若是返回動態內存分配的對象或者內存,必須使用指針,引用可能引發內存泄漏
 四。說一下對C++中四個智能指針的理解
C++裏面四個智能指針,auto_ptr,shared_ptr,weak_ptr,unique_ptr,其中後三個是C++11支持,而且第一個已經被11棄用
爲何使用智能指針:
智能指針的做用是管理一個指針,由於一下狀況:申請的空間在函數結束時忘記釋放,形成內存泄漏。使用智能指針能夠很大程度上的避免這個問題,由於智能指針就是一個類,當超出了類的做用域時,類會自動調用析構函數,析構函數會自動釋放資源。因此智能指針的做用原理就是在函數結束時自動釋放內存空間,不須要手動釋放內存空間。

1. auto_ptr(c++98的方案,cpp11已經拋棄)

採用全部權模式。

1 auto_ptr< string> p1 (new string ("I reigned lonely as a cloud.」));
2 auto_ptr<string> p2;
3 p2 = p1; //auto_ptr不會報錯.

2. unique_ptr(替換auto_ptr)

unique_ptr實現獨佔式擁有或嚴格擁有概念,保證同一時間內只有一個智能指針能夠指向該對象。它對於避免資源泄露(例如「以new建立對象後由於發生異常而忘記調用delete」)特別有用。

採用全部權模式,仍是上面那個例子

1 unique_ptr<string> p3 (new string ("auto"));   //#4
2 unique_ptr<string> p4;                       //#5
3 p4 = p3;//此時會報錯!!

編譯器認爲p4=p3非法,避免了p3再也不指向有效數據的問題。所以,unique_ptr比auto_ptr更安全。

另外unique_ptr還有更聰明的地方:當程序試圖將一個 unique_ptr 賦值給另外一個時,若是源 unique_ptr 是個臨時右值,編譯器容許這麼作;若是源 unique_ptr 將存在一段時間,編譯器將禁止這麼作,好比:

1 unique_ptr<string> pu1(new string ("hello world"));
2 unique_ptr<string> pu2;
3 pu2 = pu1;                                      // #1 not allowed
4 unique_ptr<string> pu3;
5 pu3 = unique_ptr<string>(new string ("You"));   // #2 allowed

其中#1留下懸掛的unique_ptr(pu1),這可能致使危害。而#2不會留下懸掛的unique_ptr,由於它調用 unique_ptr 的構造函數,該構造函數建立的臨時對象在其全部權讓給 pu3 後就會被銷燬。這種隨狀況而已的行爲代表,unique_ptr 優於容許兩種賦值的auto_ptr 。

注:若是確實想執行相似與#1的操做,要安全的重用這種指針,可給它賦新值。C++有一個標準庫函數std::move(),讓你可以將一個unique_ptr賦給另外一個。例如:

1 unique_ptr<string> ps1, ps2;
2 ps1 = demo("hello");
3 ps2 = move(ps1);
4 ps1 = demo("alexia");
5 cout << *ps2 << *ps1 << endl;

3. shared_ptr

shared_ptr實現共享式擁有概念。多個智能指針能夠指向相同對象,該對象和其相關資源會在「最後一個引用被銷燬」時候釋放。從名字share就能夠看出了資源能夠被多個指針共享,它使用計數機制來代表資源被幾個指針共享。能夠經過成員函數use_count()來查看資源的全部者個數。除了能夠經過new來構造,還能夠經過傳入auto_ptr, unique_ptr,weak_ptr來構造。當咱們調用release()時,當前指針會釋放資源全部權,計數減一。當計數等於0時,資源會被釋放。

shared_ptr 是爲了解決 auto_ptr 在對象全部權上的侷限性(auto_ptr 是獨佔的), 在使用引用計數的機制上提供了能夠共享全部權的智能指針。

成員函數:

use_count 返回引用計數的個數

unique 返回是不是獨佔全部權( use_count 爲 1)

swap 交換兩個 shared_ptr 對象(即交換所擁有的對象)

reset 放棄內部對象的全部權或擁有對象的變動, 會引發原有對象的引用計數的減小

get 返回內部對象(指針), 因爲已經重載了()方法, 所以和直接使用對象是同樣的.如 shared_ptr<int> sp(new int(1)); sp 與 sp.get()是等價的

 

4. weak_ptr

weak_ptr 是一種不控制對象生命週期的智能指針, 它指向一個 shared_ptr 管理的對象. 進行該對象的內存管理的是那個強引用的 shared_ptr. weak_ptr只是提供了對管理對象的一個訪問手段。weak_ptr 設計的目的是爲配合 shared_ptr 而引入的一種智能指針來協助 shared_ptr 工做, 它只能夠從一個 shared_ptr 或另外一個 weak_ptr 對象構造, 它的構造和析構不會引發引用記數的增長或減小。weak_ptr是用來解決shared_ptr相互引用時的死鎖問題,若是說兩個shared_ptr相互引用,那麼這兩個指針的引用計數永遠不可能降低爲0,資源永遠不會釋放。它是對對象的一種弱引用,不會增長對象的引用計數,和shared_ptr之間能夠相互轉化,shared_ptr能夠直接賦值給它,它能夠經過調用lock函數來得到shared_ptr。

 1 class B;
 2 class A
 3 {
 4     public:
 5     shared_ptr<B> pb_;
 6     ~A(){
 7     cout<<"A delete\n";
 8     }
 9 };
10 class B
11 {
12     public:
13     shared_ptr<A> pa_;
14     ~B()
15     {
16         cout<<"B delete\n";
17     }   
18 };
19 void fun()
20 {
21     shared_ptr<B> pb(new B());
22     shared_ptr<A> pa(new A());
23     pb->pa_ = pa;
24     pa->pb_ = pb;
25     cout<<pb.use_count()<<endl;
26     cout<<pa.use_count()<<endl;
27 }
28 int main()
29 {
30     fun();
31     return 0;
32 }

能夠看到fun函數中pa ,pb之間互相引用,兩個資源的引用計數爲2,當要跳出函數時,智能指針pa,pb析構時兩個資源引用計數會減一,可是二者引用計數仍是爲1,致使跳出函數時資源沒有被釋放(A B的析構函數沒有被調用),若是把其中一個改成weak_ptr就能夠了,咱們把類A裏面的shared_ptr pb_; 改成weak_ptr pb_; 運行結果以下,這樣的話,資源B的引用開始就只有1,當pb析構時,B的計數變爲0,B獲得釋放,B釋放的同時也會使A的計數減一,同時pa析構時使A的計數減一,那麼A的計數爲0,A獲得釋放。

注意的是咱們不能經過weak_ptr直接訪問對象的方法,好比B對象中有一個方法print(),咱們不能這樣訪問,pa->pb_->print(); 英文pb_是一個weak_ptr,應該先把它轉化爲shared_ptr,如:shared_ptr p = pa->pb_.lock(); p->print();

何時使用內聯函數

內聯函數空間換時間,在函數被調用時,將被調用部分替換成內聯函數函數體,省掉了函數調用入口,地址返回等的時間消耗,提升效率

函數體有循環和分支時不能使用內斂函數

內聯函數不能是遞歸函數

函數體通常不超過五行

 

段錯誤和頁錯誤

 

字節對齊的原理   == 進程能訪問的最大地址空間

ping的協議拼裝流程

相關文章
相關標籤/搜索