將一個類的析構函數定義爲 protected 保護類型:
這個類就不能在外部被析構,被定義。只能在它的子類,或者它的友元類裏面去定義。
定義了 保護類型的 析構函數,它的聲明週期在 子類或者 友元類裏面自動管理。
最主要理解它的限制,理解生命週期就好。
定義爲保護類型的好處:
將一個類的析構函數定義爲 protected
類型在某些情況下是有用的,主要是爲了控制類的繼承和對象的生命週期。以下是幾種情況下將析構函數定義爲 protected
的用途:
-
基類設計限制:當你設計一個基類時,你可能希望阻止其他類直接實例化該基類,而只能通過繼承該基類來創建對象。將析構函數定義爲
protected
可以防止直接實例化該基類,只有派生類才能調用基類的析構函數,從而實現了對基類對象的間接控制。 -
限制繼承:有時,你可能希望只允許特定的派生類實例化,而不是所有的派生類。將基類的析構函數定義爲
protected
可以確保只有派生類可以調用析構函數,而其他類則不能。 -
對象生命週期管理:在某些情況下,你可能需要手動管理對象的生命週期,而不是依賴於自動的棧上或堆上的對象銷燬。將析構函數定義爲
protected
可以防止用戶直接銷燬對象,只能通過派生類的方法來釋放資源,從而更靈活地管理對象的生命週期。 -
資源管理:如果類持有某些資源(如文件句柄、數據庫連接等),你可能希望確保這些資源在對象銷燬時得到正確釋放。將析構函數定義爲
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 析構函數被調用