C++的保護類型還能這麼玩

將一個類的析構函數定義爲  protected 保護類型:

這個類就不能在外部被析構,被定義。只能在它的子類,或者它的友元類裏面去定義。

定義了 保護類型的 析構函數,它的聲明週期在 子類或者 友元類裏面自動管理。

最主要理解它的限制,理解生命週期就好。

 

定義爲保護類型的好處:

將一個類的析構函數定義爲 protected 類型在某些情況下是有用的,主要是爲了控制類的繼承和對象的生命週期。以下是幾種情況下將析構函數定義爲 protected 的用途:

  1. 基類設計限制:當你設計一個基類時,你可能希望阻止其他類直接實例化該基類,而只能通過繼承該基類來創建對象。將析構函數定義爲 protected 可以防止直接實例化該基類,只有派生類才能調用基類的析構函數,從而實現了對基類對象的間接控制。

  2. 限制繼承:有時,你可能希望只允許特定的派生類實例化,而不是所有的派生類。將基類的析構函數定義爲 protected 可以確保只有派生類可以調用析構函數,而其他類則不能。

  3. 對象生命週期管理:在某些情況下,你可能需要手動管理對象的生命週期,而不是依賴於自動的棧上或堆上的對象銷燬。將析構函數定義爲 protected 可以防止用戶直接銷燬對象,只能通過派生類的方法來釋放資源,從而更靈活地管理對象的生命週期。

  4. 資源管理:如果類持有某些資源(如文件句柄、數據庫連接等),你可能希望確保這些資源在對象銷燬時得到正確釋放。將析構函數定義爲 protected 可以讓你控制資源的釋放過程,並確保資源在適當的時候被釋放,避免資源泄漏。

總的來說,將析構函數定義爲 protected 類型可以提供更加靈活的對象生命週期管理和資源管理機制,並控制對象的繼承和銷燬行爲,從而增強了類的封裝性和安全性。

 

#include <iostream>
#include <cstdint>
#include <string>
#include <cstring>


class BaseA {
protected:
    BaseA() { std::cout << "BaseA 構造函數被調用" << std::endl; }
    ~BaseA() { std::cout << "BaseA 析構函數被調用" << std::endl; }

    friend class BaseB; // 將BaseB聲明爲友元類
public:
    void print() { std::cout << "這是BaseA類的print函數" << std::endl; }    
};

class BaseB {
private:
    BaseA objA;  // BaseA的對象作爲成員變量

protected:
    BaseB() { std::cout << "------- BaseB 構造函數被調用" << std::endl; }
    ~BaseB() { std::cout << "------- BaseB 析構函數被調用" << std::endl; }

public:
    void print() { 
        std::cout << "------- 這是BaseB類的print函數" << std::endl; 
        objA.print(); // 調用BaseA類的print函數
    }
};

class DriveC : public BaseB {
public:
    DriveC() { std::cout << "<<<----->>> DriveC 構造函數被調用" << std::endl; }
    ~DriveC() { std::cout << "<<<----->>> DriveC 析構函數被調用" << std::endl; }

    void print() { 
        std::cout << "<<<----->>> 這是DriveC類的print函數" << std::endl; 
        BaseB::print(); // 調用BaseB類的print函數
    }
};




int main(){

   
    DriveC c;  // 創建DriveC對象
    std::cout<<"-------------------------------------------\r\n";
    c.print(); // 調用DriveC對象的print函數

   
    return 0;
}

輸出結果:

BaseA 構造函數被調用
------- BaseB 構造函數被調用
<<<----->>> DriveC 構造函數被調用
-------------------------------------------
<<<----->>> 這是DriveC類的print函數
------- 這是BaseB類的print函數
這是BaseA類的print函數
<<<----->>> DriveC 析構函數被調用
------- BaseB 析構函數被調用
BaseA 析構函數被調用

 

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