首頁>技術>

本期是C++基礎語法分享的第六節,今天給大家來分享一下:

(1)引用;

(2)宏;

(3)成員初始化列表;

(4)封裝;

(5)繼承;

(6)多型;

引用

左值引用

常規引用,一般表示物件的身份。

右值引用

右值引用就是必須繫結到右值(一個臨時物件、將要銷燬的物件)的引用,一般表示物件的值。

右值引用可實現轉移語義(Move Sementics)和精確傳遞(Perfect Forwarding),它的主要目的有兩個方面:

消除兩個物件互動時不必要的物件複製,節省運算儲存資源,提高效率。

能夠更簡潔明確地定義泛型函式。

引用摺疊

X& &、X& &&、X&& & 可摺疊成 X&

X&& && 可摺疊成 X&&

宏定義可以實現類似於函式的功能,但是它終歸不是函式,而宏定義中括弧中的“引數”也不是真的引數,在宏展開的時候對 “引數” 進行的是一對一的替換。

成員初始化列表

好處

更高效:少了一次呼叫預設建構函式的過程。

有些場合必須要用初始化列表:

常量成員,因為常量只能初始化不能賦值,所以必須放在初始化列表裡面

引用型別,引用必須在定義的時候初始化,並且不能重新賦值,所以也要寫在初始化列表裡面

沒有預設建構函式的類型別,因為使用初始化列表可以不必呼叫預設建構函式來初始化

initializer_list 列表初始化

用花括號初始化器列表初始化一個物件,其中對應建構函式接受一個 std::initializer_list 引數.

initializer_list 使用

#include <iostream>#include <vector>#include <initializer_list> template <class T>struct S {    std::vector<T> v;    S(std::initializer_list<T> l) : v(l) {         std::cout << "constructed with a " << l.size() << "-element list\n";    }    void append(std::initializer_list<T> l) {        v.insert(v.end(), l.begin(), l.end());    }    std::pair<const T*, std::size_t> c_arr() const {        return {&v[0], v.size()};  // 在 return 語句中複製列表初始化                                   // 這不使用 std::initializer_list    }}; template <typename T>void templated_fn(T) {} int main(){    S<int> s = {1, 2, 3, 4, 5}; // 複製初始化    s.append({6, 7, 8});      // 函式呼叫中的列表初始化     std::cout << "The vector size is now " << s.c_arr().second << " ints:\n";     for (auto n : s.v)        std::cout << n << ' ';    std::cout << '\n';     std::cout << "Range-for over brace-init-list: \n";     for (int x : {-1, -2, -3}) // auto 的規則令此帶範圍 for 工作        std::cout << x << ' ';    std::cout << '\n';     auto al = {10, 11, 12};   // auto 的特殊規則     std::cout << "The list bound to auto has size() = " << al.size() << '\n'; //    templated_fn({1, 2, 3}); // 編譯錯誤!“ {1, 2, 3} ”不是表示式,                             // 它無型別,故 T 無法推導    templated_fn<std::initializer_list<int>>({1, 2, 3}); // OK    templated_fn<std::vector<int>>({1, 2, 3});           // 也 OK}

面向物件

面向物件程式設計(Object-oriented programming,OOP)是種具有物件概念的程式程式設計典範,同時也是一種程式開發的抽象方針。

面向物件三大特徵 —— 封裝、繼承、多型

封裝

把客觀事物封裝成抽象的類,並且類可以把自己的資料和方法只讓可信的類或者物件操作,對不可信的進行資訊隱藏。關鍵字:public, protected, private。不寫預設為 private。

public 成員:可以被任意實體訪問

protected 成員:只允許被子類及本類的成員函式訪問

private 成員:只允許被本類的成員函式、友元類或友元函式訪問

繼承

基類(父類)——> 派生類(子類)

多型

多型,即多種狀態(形態)。簡單來說,我們可以將多型定義為訊息以多種形式顯示的能力。

多型是以封裝和繼承為基礎的。

C++ 多型分類及實現:

過載多型(Ad-hoc Polymorphism,編譯期):函式過載、運算子過載

子型別多型(Subtype Polymorphism,執行期):虛擬函式

引數多型性(Parametric Polymorphism,編譯期):類模板、函式模板

強制多型(Coercion Polymorphism,編譯期/執行期):基本型別轉換、自定義型別轉換

靜態多型(編譯期/早繫結)

函式過載

class A{public:    void do(int a);    void do(int a, int b);};

動態多型(執行期期/晚繫結)

虛擬函式:用 virtual 修飾成員函式,使其成為虛擬函式

動態繫結:當使用基類的引用或指標呼叫一個虛擬函式時將發生動態繫結

注意:

可以將派生類的物件賦值給基類的指標或引用,反之不可

普通函式(非類成員函式)不能是虛擬函式

靜態函式(static)不能是虛擬函式

建構函式不能是虛擬函式(因為在呼叫建構函式時,虛表指標並沒有在物件的記憶體空間中,必須要建構函式呼叫完成後才會形成虛表指標)

行內函數不能是表現多型性時的虛擬函式

動態多型使用

class Shape                     // 形狀類{public:    virtual double calcArea()    {        ...    }    virtual ~Shape();};class Circle : public Shape     // 圓形類{public:    virtual double calcArea();    ...};class Rect : public Shape       // 矩形類{public:    virtual double calcArea();    ...};int main(){    Shape * shape1 = new Circle(4.0);    Shape * shape2 = new Rect(5.0, 6.0);    shape1->calcArea();         // 呼叫圓形類裡面的方法    shape2->calcArea();         // 呼叫矩形類裡面的方法    delete shape1;    shape1 = nullptr;    delete shape2;    shape2 = nullptr;    return 0;}

今天的分享就到這裡了,大家要好好學C++喲~

寫在最後:對於準備學習C/C++程式設計的小夥伴,如果你想更好的提升你的程式設計核心能力(內功)不妨從現在開始!

程式設計學習書籍分享:

程式設計學習影片分享:

整理分享(多年學習的原始碼、專案實戰影片、專案筆記,基礎入門教程)

4
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 十分鐘徹底掌握快取擊穿、快取穿透、快取雪崩