複習C++語法--基礎篇

1,生成一個C++程序共有三個步驟。首先,代碼在預處理器中運行,預處理器會識別代碼中的元信息。其次,代碼被編譯或轉換成計算機可識別的目標文件。最後,獨立的目標文件被連接在一塊兒變成一個應用程序。

2,名稱空間

定義:namespace mycode { void foo(); }
實現:void mycode::foo() { ... }
使用方法:a, using namespace mycode;  foo();    b, using mycode::foo;  foo();
C++17中的名稱空間嵌套:namespace MyLib::NewWorking::FTP { ... }
給名稱空間起別名:namespace MyFTP = MyLib::NewWorking::FTP;

3,類型轉換

float myFloat = 3.14f;
int i3 = static_cast<int>(myFloat);

4,強類型的enum class:

定義:enum class PieceType { King = 1, Queen, Rook = 10, Pawn };
使用:PieceType  piece = PieceType::King;
枚舉值不會自動轉換爲整數:if (PieceType::Queen == 2) { ... }   // 這段代碼不合法
能夠這樣改變枚舉值類型(默認是整型):
enum class PieceType : unsigned long { King = 1, Queen, Rook = 10, Pawn };

5,if 語句的初始化器

if ( Employee employee = GetEmployee(); employee.salary > 1000 ) { ... }
switch 語句也有這種用法

6,數組與容器

array<int, 3> arr = { 1, 2, 3 };
vector<int> myArr = { 11, 22, 33 };

7,基於區間的for循環

std::array<int, 4> arr = { 1, 2, 3, 4 };
for ( int i : arr ) { std::cout << i << std::endl; }

8,初始化列表

利用初始化列表可輕鬆地編寫能接收可變數量參數的函數
#include <initializer_list>
using namespace std;
int makeSum( initializer_list<int> lst )
{
      int total = 0;
      for ( int value : lst ) { total += value }
      return total;
}
int c = makeSum( {1, 2, 3, 4, 5} );

9,空指針在布爾表達式中使用時會被轉換爲false,對null或未初始化的指針解除引用會致使不可肯定行爲

10,動態分配數組

int arrSize = 8;
int* myVariableSizeArr = new int[arrSize];
指針變量仍在堆棧中,但動態建立的數組在堆中

11,C++11以前,常量NULL用於表示空指針,將NULL定義爲常量0會致使一些問題,應使用nullptr;

12,智能指針

std::unique_ptr
auto employee = make_unique<Employee>();
auto employee = make_unique<Employee[]>(10);  employee[0].salary = 1000;

std::shared_ptr
auto employee = make_shared<Employee>();
shared_ptr<Employee[]> employee(new Employee[10]);

13,引用

int x = 32;
int& xReference = x;
按引用傳參的函數傳遞字面量是會編譯錯誤

14,異常

#include <stdexcept>
double divideNumbers(double numerator, double denominator)
{
      if ( denominator == 0 )
            throw invalid_argument("Denominator cannot be 0.");
      return numerator / denominator
}
try {
      cout << divideNumbers(2.5, 0.5) << endl;
      cout << divideNumbers(3.2, 0) << endl;
      cout << divideNumbers(5.2, 1.2) << endl;  // 第二句報錯,此句不會執行
} catch (const invalid_argument& exception) {
      cout << "Exception caught: " << exception.what() << endl;
}

15,類型推斷

auto: auto去除了引用和const限定符,會創造副本!若是不須要副本,可以使用auto& 或 const auto&
decltype: 把表達式做爲實參,計算出該表達式的類型,decltype不會除了引用和const限定符!int x = 123;  decltype(x) y = 234;

16,類與對象,若是構造函數只是初始化數據成員而不作其餘事,實際上沒有必要使用構造函數,由於可在類定義中直接初始化數據成員

17,統一初始化

CircleStruct myCircle1 = { 10, 10, 2.5 };
CircleClass myCircle2 = { 10, 10, 2.5};
CircleStruct myCircle3 { 10, 10, 2.5 };
CircleClass myCircle4 { 10, 10, 2.5};  // 這四句同樣效果
並不侷限於結構體和類,例如:
int a = 3;
int b(3);
int c = {3};
int d{3};  // 這四句效果也同樣
統一初始化還可用於將變量初始化爲0,只須要指定對應的空大括號:int e{};
統一初始化還能夠阻止C++隱式的窄化,如:
int x = 3.14;  // 有些編譯器只會發出警告甚至沒有警告
int x = {3.14};  // 這樣編譯會報錯
統一初始化還能夠動態分配數組:int* pArr = new int[4]{1, 2, 3, 4};

18,直接列表初始化與複製列表初始化

從C++17開始:
// 複製列表初始化
auto a = {11};
auto b = {11, 22};
// 直接列表初始化
auto c {11};
auto d {11, 22};  // 報錯,太多元素
相關文章
相關標籤/搜索