C++基礎知識面試必備、複習細節 (8)(tuple、隨機數、異常處理、多繼承)

C++基礎知識面試必備、複習細節 (8)(tuple、隨機數、異常處理、多繼承)

tuple類型
  • tuple是一個類似於pair的模板,pair類型是每個成員變量各自可以是任意類型,但是隻能有兩個成員,而tuple與pair不同的是它可以有任意數量的成員

  • 個人常把tuple當作一個結構體使用,如果只是一次使用的話就避免了結構體繁瑣的創建

  • tuple的基本操作:

    tuple<int,string,int> t{1,"James",1000}; //可以用來存一個序號,名字,工資這樣的信息
    auto t=make_tuple("1","James","12345678911");  //存序號,名字,電話 用auto可以自動判斷
    auto name=get<1>(t); //返回名字  通過get<i>(tuple)返回第i-1個成員對象
    get<2>(t)="98765432111";  //get<>()返回的是引用,因此可以修改
    
  • 兩個tuple相等當且僅當元素數量相同且每個元素相等,< 也是同理

  • 通過使用tuple可以令一個函數中返回多個值, 有時候可以令程序更簡潔方便

隨機數
  • 頭文件: random

  • c++的隨機數通過兩部分解決隨機數問題:隨機數引擎類和隨機數分佈類

    隨機數引擎類生成隨機的unsigned整數序列,隨機數分佈類使用引擎返回特定概率分佈的隨機數

  • 常用的默認隨機數引擎生成隨機數:

       default_random_engine e;
        for (int i = 0; i < 10;i++)
            cout << e() << ' ';
    /* 16807 282475249 1622650073 984943658 1144108930 470211272 101027544 1457850878 1458777923 2007237709 */
    
  • 使用分佈類型的對象得到指定範圍的隨機數

        uniform_int_distribution<unsigned> u(0, 9);  //生成0-9的隨機數
        default_random_engine e;
        for (int i = 0; i < 10; i++)
            cout << u(e) << ' ';
    //0 1 7 4 5 2 0 6 6 9
    
  • 一個給定的隨機數發生器一直會生成相同的隨機數序列。一個函數如果定義了局部的隨機數發生器,應該將其(包括引擎和分佈對象)定義爲static的,否則每次調用生成相同的序列。

  • 生成正態分佈序列

        default_random_engine e;
        normal_distribution<> n(4, 1.5); //均值爲4,標準差爲1.5的正態分佈
        for (int i = 0; i < 10; i++)
            cout << n(e) << ' ';
    //3.81705 2.36977 5.02643 2.38722 4.0499 5.11725 4.05041 3.21004 4.6938 4.30105
    
  • 生成伯努利分佈序列(true or false 可以制定概率)

       default_random_engine e;
        bernoulli_distribution n(0.9); //伯努利實驗的p=0.9
        for (int i = 0; i < 10; i++)
            cout << n(e) << ' ';
    //1 1 1 1 0 1 1 1 1 1
    
IO庫
  • 八進制十六進制十進制

        cout<<hex<<20<<endl;  //14             將cout輸出的整數轉換爲16進制
        cout<<oct<<10<<endl;  //12 			   將cout輸出的整數轉換爲8進制
        cout << dec << 10<<endl;//10         將cout輸出的整數轉換爲10進制
        cout<<0x20<<endl;   //0x開頭表示十六進制  32
        cout << 010 << endl;  //0開頭表示八進制   8
    
  • 浮點數輸出格式

    	//制定打印精度
        double t = 3.1415926;
        cout.precision(3); //浮點數精度爲3
        cout << t << endl;  //3.14
        cout.precision(5);
        cout <<t << endl;  //3.1416
    
異常處理
  • 執行throw時,跟在throw後面的語句將不再執行,程序的控制權從throw轉移到catch塊。因此,儘量不要在析構函數中寫異常處理,避免內存泄漏。

  • 棧展開:對於拋出異常的函數的調用語句位於一個try語句塊內,則檢查與該try塊關聯的catch語句。如果找到了匹配的catch,則用該catch處理異常,否則如果該try語句嵌套在其他try塊中,則繼續檢查與外層try匹配的catch語句,如果還沒找到則退出當前的主調函數,繼續在調用了這個函數的其他函數中尋找。

    棧展開過程也就是沿着嵌套函數的調用鏈不斷查找,直到找到了與異常匹配的catch子句爲止,或者一直沒找到,退出主函數後終止查找過程。

  • 一個異常沒被捕獲,則將終止程序

  • 構造函數中拋出異常,會導致析構函數不能被調用,但對象本身已申請到的內存資源會被系統釋放

因爲析構函數不能被調用,所以可能會造成內存泄露或系統資源未被釋放

構造函數中可以拋出異常,但必須保證在構造函數拋出異常之前,把系統資源釋放掉,防止內存泄露

  • 不要在析構函數中拋出異常

    如果某個操作可能會拋出異常,class應提供一個普通函數(而非析構函數),來執行該操作

    如果析構函數中異常非拋不可,那就用try catch來將異常吞下,不要讓異常逃離析構函數

  •    try
        {
            //something
        }
        catch (exception &e)
        {
            cout << "Standard exception: " << e.what() << endl;
        }
    
多繼承
  • 如果從多個基類中繼承了相同的構造函數,則該類必須定義自己的構造函數
  • 當一個類擁有多個基類時,可能出現派生類從兩個或多個基類中繼承了同名成員的情況,則需要用前綴限定符訪問該函數,否則會有二義性
  • 虛繼承:令某個類做出聲明,使其共享基類。在這樣的情況下,虛基類被多次繼承,也只有一個共享的基類 virtual public A
  • 虛派生隻影響從指定了虛基類的派生類中進一步派生出的類,它不會影響派生類本身
  • 虛基類總是先於非虛基類構造,與它們在繼承體系中的次序和爲止無關
  • 多繼承的父類的構造順序,只與繼承的順序有關,與成員初始化列表順序無關
  • 多繼承的構造函數的順序:
    • 虛基類的構造函數按照它們被繼承的順序構造
    • 非虛基類的構造函數按照它們被繼承的順序構造;
    • 成員對象的構造函數按照它們聲明的順序調用
    • 類自己的構造函數
  • 析構函數調用順序與構造函數相反
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章