C++知識點總結(面向對象4-多繼承, 靜態成員static)

多繼承1-虛函數

如果子類繼承的多個父類都有虛函數, 那麼子類對象就會產生對應的多張虛表.
在這裏插入圖片描述

同名函數

在這裏插入圖片描述

同名成員變量

在這裏插入圖片描述

多繼承2-菱形繼承

在這裏插入圖片描述
菱形繼承帶來的問題:
最底下子類從基類繼承的成員變量冗餘, 重複(有兩個age, 內存是兩份, 從語法上正確, 但不合理)
最底下子類無法訪問基類的成員, 有二義性.

多繼承3-虛繼承

虛繼承可以解決菱形繼承帶來的問題
在這裏插入圖片描述
Student和Worker共用一個age, 共享
從虛基類裏面搞過來的成員變量都放到最後面, 這個對象會多出4個字節, 存放虛表指針, 20和12是拿來尋找age的, 拿來定位虛基類的成員變量在哪裏, 因爲age是共享的, 所以就要保證不管是從Worker這個類開始找還是從Student這個類開始找, 都能找到age.
在這裏插入圖片描述
在這裏插入圖片描述
Person類被稱爲虛基類

靜態成員(static)

◼ 靜態成員:被static修飾的成員變量\函數
□可以通過對象(對象.靜態成員)、對象指針(對象指針->靜態成員)、類訪問(類名::靜態成員)
◼ 靜態成員變量
存儲在數據段(全局區,類似於全局變量),整個程序運行過程中只有一份內存, 不在類裏面
□ 對比全局變量,它可以設定訪問權限(public、protected、private),達到局部共享的目的
必須初始化,必須在類外面初始化,初始化時不能帶static,如果類的聲明和實現分離(在實現.cpp中初始化)
◼ 靜態成員函數
□ 內部不能使用this指針(this指針只能用在非靜態成員函數內部)
□ 不能是虛函數(虛函數只能是非靜態成員函數)
□ 內部不能訪問非靜態成員變量\函數,只能訪問靜態成員變量\函數
□ 非靜態成員函數內部可以訪問靜態成員變量\函數
□ 構造函數、析構函數不能是靜態
□ 當聲明和實現分離時,實現部分不能帶static

靜態成員經典應用-單例模式

單例模式:設計模式的一種, 保證某個類永遠只創建一個對象.
1.構造函數\析構函數私有化, 拷貝構造函數私有化, 賦值運算符重載函數私有化.
2.定義一個私有的static成員變量指向唯一的那個單例對象
3.提供一個公共的訪問單例對象的接口.

#include <iostream>
using namespace std;

class Rocket {
private:
    Rocket() {}
    static Rocket *ms_rocket;
public:
    static Rocket *sharedRocket() {
    	// 這裏要考慮多線程安全
        if (ms_rocket == NULL) {
            ms_rocket = new Rocket();
        }
        return ms_rocket;
    }

    static void deleteRocket() {
    	// 這裏要考慮多線程安全
        if (ms_rocket != NULL) {
            delete ms_rocket;
            ms_rocket = NULL;
            // 防止野指針
        }
    }
    
    void run() {
        cout << "run()" << endl;
    }
};

Rocket *Rocket::ms_rocket = NULL;

int main()
{
    Rocket *p = Rocket::sharedRocket();
    p->run();
    p->deleteRocket();
    return 0;
}

(1)爲什麼要用指針?
1.在C++開發中, 對象能放堆空間, 儘量放堆空間.
2.對於單例對象, 要考慮內存的靈活使用, 因爲牽扯到內存的分配和銷燬, 所以用堆空間更靈活.
(2)賦值運算符重載函數爲什麼要私有化?
因爲兩個一樣的對象做賦值操作沒有意義.
(3)拷貝構造函數爲什麼要私有化?
因爲如果不寫拷貝構造函數, 還可以通過調用默認的拷貝構造函數去構建對象.如:

Rocket *p1 = Rocket::sharedRocket();
Rocket *p2 = new Rocket(*p1)

其他C++系列文章:

C++知識點總結(基礎語法1-函數重載, 默認參數)
C++知識點總結(基礎語法2-內聯函數, const, 引用)
C++知識點總結(面向對象1-類和對象, this指針, 內存佈局)
C++知識點總結(面向對象2-構造函數, 初始化列表)

C++知識點總結(面向對象3-多態)

C++知識點總結(面向對象4-多繼承, 靜態成員static)
C++知識點總結(面向對象5-const成員, 拷貝構造函數)
C++知識點總結(面向對象6-隱式構造, 友元, 內部類, 局部類)
C++知識點總結(其他語法1-運算符重載)
C++知識點總結(其他語法2-模板, 類型轉換, C++11新特性)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章