C++ 11/14特性備忘

  • nullptr 出現的目的是爲了替代 NULL。在某種意義上來說,傳統 C++ 會把 NULL、0 視爲同一種東西,這取決於編譯器如何定義 NULL,有些編譯器會將 NULL 定義爲 ((void*)0),有些則會直接將其定義爲 0。
  • nullptr 的類型爲 nullptr_t,能夠隱式的轉換爲任何指針或成員指針的類型,也能和他們進行相等或者不等的比較(而不會出現編譯無法通過的情況)。
  • C++ 11 提供了 constexpr 讓用戶顯式的聲明函數或對象構造函數在編譯器會成爲常數,這個關鍵字明確的告訴編譯器應該去驗證 len_foo 在編譯器就應該是一個常數。
  • 從 C++ 14 開始,constexptr 函數可以在內部使用局部變量、循環和分支等簡單語句,但 C++ 11 中是不可以的。
  • auto自動類型推導無法用於函數傳參
  • decltype(表達式)在此過程中,編譯器分析表達式並得到它的類型,卻不實際計算表達式的值。
  • C++14中下面的寫法變得合法,C++11必須使用尾返回類型(trailing return type)解決這個問題:
template<typename T, typename U>
auto add(T x, U y) {
    return x+y;
}
  • C++11引入了區間迭代
int array[] = {1,2,3,4,5};
for(auto &x : array) {
    std::cout << x << std::endl;
}
  • 初始化列表
#include <initializer_list>
//構造函數列表初始化
class Magic {
public:
    Magic(std::initializer_list<int> list) {}
};

Magic magic = {1,2,3,4,5};
std::vector<int> v = {1, 2, 3, 4};
//普通函數形參
void func(std::initializer_list<int> list) {
    return;
}

func({1,2,3});
//初始化任意對象
struct A {
    int a;
    float b;
};
struct B {

    B(int _a, float _b): a(_a), b(_b) {}
private:
    int a;
    float b;
};

A a {1, 1.1};    // 統一的初始化語法
B b {2, 2.2};
  • 模板實例化標註(傳統C++會在每一次使用時被編譯器實例化)
template class std::vector<bool>;            // 強行實例化
extern template class std::vector<double>;  // 不在該編譯文件中實例化模板 
  • C++11開始,連續的右尖括號將會變得合法
  • 類型別名模板
typedef int (*process)(void *);  // 定義了一個返回類型爲 int,參數爲 void* 的函數指針類型,名字叫做 process
using process = int(*)(void *); // 同上, 更加直觀

template <typename T>
using NewType = SuckType<int, T, 1>;    // 合法
  • 委託構造
class Base {
public:
    int value1;
    int value2;
    Base() {
        value1 = 1;
    }
    Base(int value) : Base() {  // 委託 Base() 構造函數
        value2 = 2;
    }
};

int main() {
    Base b(2);
    std::cout << b.value1 << std::endl;
    std::cout << b.value2 << std::endl;
}
  • 繼承構造
class Base {
public:
    int value1;
    int value2;
    Base() {
        value1 = 1;
    }
    Base(int value) : Base() {                          // 委託 Base() 構造函數
        value2 = 2;
    }
};
class Subclass : public Base {
public:
    using Base::Base;  // 繼承構造
};
int main() {
    Subclass s(3);
    std::cout << s.value1 << std::endl;
    std::cout << s.value2 << std::endl;
}
  • 使用override和final防止意外重載虛函數和父類虛函數被刪除後子類同樣被刪除的情況
  • 當重載虛函數時,引入 override 關鍵字將顯式的告知編譯器進行重載,編譯器將檢查基函數是否存在這樣的虛函數,否則將無法通過編譯
  • final 則是爲了防止類被繼續繼承以及終止虛函數繼續重載引入的(使用final將不允許被繼續繼承下去)
  • 模板函數
template <typename T>
T  add(const T lva ,const T rva)
{

    T a ;

    a = lva + rva ;

return a;
}
  • 成員模板
 template <class T>
 class Myclass
 {
     public:
        T a;
        template <typename type_1 , typename type_2>
         type_1 add(const type_1 lva ,const type_2 rva);
 };

 template <class T>
     template <typename type_1,typename type_2>
 type_1 Myclass<T>::add(const type_1 lva, const type_2 rva)
 {
     a = lva + rva;
     return a;
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章