Xét đoạn mã sau:Khi nào bạn nên hạn chế khả năng truy cập vào một chức năng ảo trong một lớp dẫn xuất?
class Base
{
public:
virtual void Foo() {}
};
class Derived : public Base
{
private:
void Foo() {}
};
void func()
{
Base* a = new Derived;
a->Foo(); //fine, calls Derived::Foo()
Derived* b = new Derived;
// b->Foo(); //error
static_cast<Base*>(b)->Foo(); //fine, calls Derived::Foo()
}
Tôi đã nghe hai trường phái khác nhau về vấn đề này:
1) Để lại khả năng tiếp cận giống như các lớp cơ sở, vì người dùng có thể sử dụng để truy cập static_cast dù sao.
2) Đặt các chức năng ở chế độ riêng tư nhất có thể. Nếu người dùng yêu cầu a-> Foo() nhưng không phải b-> Foo(), thì Derived :: Foo phải là riêng tư. Nó luôn luôn có thể được công khai nếu và khi đó là cần thiết.
Có lý do nào để thích cái này hay cái kia không?
Thiết kế này rất phản trực giác vì những lý do bạn đề cập. Tôi sẽ khuyên bạn nên chống lại nó trừ khi bạn gặp phải một kịch bản mà chỉ có thể được giải quyết theo cách này. –
Nếu mục đích của bạn là hạn chế việc sử dụng _direct_ của lớp dẫn xuất (ví dụ: Mẫu nhà máy), thì bảo vệ hoặc riêng tư _inheritance_ là cách thích hợp hơn (thay vì hạn chế các phương thức cụ thể) – user396672