Bjarne Stroustrup đã viết về điều này here.
Các bit có liên quan từ liên kết:
Tôi có thể ngăn không cho người bắt nguồn từ lớp học của tôi?
Có, nhưng tại sao bạn muốn? Có hai câu trả lời phổ biến:
- để biết hiệu quả: để tránh chức năng của tôi gọi là ảo.
- cho an toàn: để đảm bảo rằng lớp học của tôi không được sử dụng như là một lớp cơ sở (ví dụ, để chắc chắn mà tôi có thể sao chép đối tượng mà không sợ của slicing)
Theo kinh nghiệm của tôi, hiệu quả lý do thường là không đúng chỗ sợ hãi. Trong C++, các lời gọi hàm ảo nhanh đến nỗi việc sử dụng thế giới thực của họ cho một lớp được thiết kế với các hàm ảo không tạo ra chi phí thời gian chạy có thể đo lường được so với các giải pháp thay thế sử dụng các cuộc gọi hàm bình thường. Lưu ý rằng cơ chế gọi hàm ảo thường chỉ được sử dụng khi gọi qua một con trỏ hoặc một tham chiếu. Khi gọi một hàm trực tiếp cho một đối tượng được đặt tên, lớp chức năng ảo trên cao sẽ dễ dàng được tối ưu hóa.
Nếu có nhu cầu chính xác về "giới hạn" một hệ thống phân cấp lớp để tránh các cuộc gọi chức năng ảo, người ta có thể hỏi tại sao những chức năng đó là ảo ngay từ đầu. Tôi đã thấy các ví dụ về các chức năng quan trọng về hiệu suất đã được thực hiện ảo vì không có lý do chính đáng, chỉ vì "đó là cách chúng ta thường làm".
Biến thể khác của vấn đề này, cách ngăn chặn dẫn xuất vì lý do logic, có giải pháp. Thật không may, giải pháp đó không phải là khá. Nó dựa trên thực tế là lớp dẫn xuất nhất trong một hệ thống phân cấp phải xây dựng một cơ sở ảo. Ví dụ:
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
// ...
public:
Usable();
Usable(char*);
// ...
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD::DD() cannot access
// Usable_lock::Usable_lock(): private member
(từ D&E giây 11.4.3).
Nguồn
2009-06-16 11:39:40
Ah và đó có thể là phương pháp nhà máy tĩnh của lớp học để giữ mọi thứ cùng nhau? Nghe có vẻ tốt đấy. – SebastianK
Không may mắn thay, điều này không dừng lại nguồn gốc.Nó chỉ đơn thuần ngăn cản sự xâm nhập của loại dẫn xuất, ngoại trừ thông qua nhà máy. Sẽ thật tuyệt nếu bạn thực sự có thể tạo ra nguồn gốc, nhưng theo tôi biết, bạn không thể. –
Trong cách thực tế nào có sự khác biệt giữa việc không thể khởi tạo một đối tượng của kiểu dẫn xuất và không thể lấy được ở tất cả (truy cập vào các thành viên tĩnh được bảo vệ?) – Motti