Chỉ là một ví dụ tôi đã sử dụng trong quá khứ. Các phương thức được bảo vệ là tuyệt vời để cung cấp các chức năng dành riêng cho việc triển khai, đồng thời cho phép lớp cơ sở theo dõi đúng mọi thứ. Hãy xem xét một lớp cơ sở cung cấp hàm khởi tạo có thể ghi đè, nhưng cũng phải có trạng thái để xác định nếu được khởi tạo:
class Base
{
private:
bool m_bInitialized;
public:
virtual void Initialize() = 0;
void setInitialized() { m_bInitialized = true; };
bool isInitialized() const { return m_bInitialized; };
}; // eo class Base
Tất cả đều tốt và tốt ở đây. Ngoại trừ khi một lớp dẫn xuất không bận tâm gọi setInitialized()
ít nhất là thực tế là bất kỳ ai cũng có thể gọi nó (chúng ta có thể làm cho điều này được bảo vệ ở đây và một lý do khác để sử dụng các phương thức được bảo vệ!). Tôi rất thích một lớp sử dụng các thành viên được bảo vệ ảo:
class Base
{
private:
bool m_bInitialized;
protected:
virtual void InitializeImpl() = 0;
public:
void Initialize()
{
InitializeImpl();
m_bInitialized = true;
}; // eo Initialize
bool isInitialized() const { return m_bInitialized; };
}; // eo class Base
Trong lớp mới của chúng tôi, tất cả các khởi tạo vẫn được ủy quyền cho lớp dẫn xuất. Cung cấp một ngoại lệ như đã được ném, chúng tôi duy trì hợp đồng "lớp này được khởi tạo" mà phương thức của chúng tôi nói sẽ xảy ra.