Thừa kế ảo chỉ có liên quan nếu các lớp học được kế thừa từ Foo
.Nếu tôi xác định như sau:
class B {};
class L : virtual public B {};
class R : virtual public B {};
class D : public L, public R {};
Sau đó, đối tượng cuối cùng sẽ chỉ chứa một bản sao của B
, chia sẻ bởi cả hai L
và R
. Nếu không có virtual
, một đối tượng thuộc loại D
sẽ chứa hai bản sao của B
, một trong số L
và một trong số R
.
Có một số tranh luận rằng tất cả thừa kế phải là ảo (vì trong trường hợp tạo sự khác biệt, đó là điều bạn muốn nhất trong số thời gian). Tuy nhiên, trong thực tế, thừa kế ảo rất đắt và trong hầu hết các trường hợp, không cần thiết: trong một hệ thống được thiết kế tốt, hầu hết thừa kế sẽ đơn giản là lớp bê tông kế thừa từ một hoặc nhiều giao diện hơn; một lớp bê tông như vậy thường không được thiết kế để được bắt nguồn từ chính nó, vì vậy không có vấn đề gì. Nhưng có một số trường hợp ngoại lệ quan trọng: nếu, ví dụ, bạn định nghĩa một giao diện, và sau đó là mở rộng cho giao diện, phần mở rộng sẽ thừa kế hầu như từ giao diện cơ sở, vì việc triển khai cụ thể có thể muốn triển khai một số tiện ích mở rộng. Hoặc nếu bạn đang thiết kế mixin, trong đó một số lớp nhất định chỉ thực hiện một phần của giao diện và lớp cuối cùng được thừa kế từ một vài trong số các lớp này (một phần của giao diện ). Cuối cùng, các criteron là liệu kế thừa hầu hay không không phải là quá khó khăn:
nếu thừa kế không được công khai, thì có lẽ không nên ảo (Tôi chưa từng thấy một ngoại lệ), nếu không
nếu lớp không được thiết kế để trở thành một lớp cơ sở, không có nhu cầu thừa kế ảo, nếu không
thừa kế nên ảo.
Có một vài ngoại lệ, nhưng các quy tắc trên sai ở bên cạnh an toàn ; thường là "chính xác" để kế thừa hầu như ngay cả trong trường hợp thừa kế ảo là không cần thiết.
Một điểm cuối cùng: một cơ sở ảo phải luôn luôn được khởi tạo bởi lớp nhất có nguồn gốc, không lớp mà trực tiếp thừa hưởng (và tuyên bố rằng các thừa kế là ảo). Tuy nhiên, trong thực tế, đây không phải là vấn đề. Nếu bạn xem xét các trường hợp thừa kế ảo có ý nghĩa, thì luôn là trường hợp kế thừa từ giao diện, sẽ không chứa dữ liệu và do đó chỉ có một hàm tạo mặc định. Nếu bạn thấy mình kế thừa hầu như từ các lớp học với các nhà thầu thực hiện các đối số , đã đến lúc đặt một số câu hỏi nghiêm túc về thiết kế.
Nguồn
2011-11-16 09:35:06
Tôi sẽ không trả lời vì chủ đề không thực sự đáng được xử lý nông như vậy: nhưng không có 'virtual' mỗi lớp thừa kế từ' Bar' sẽ có bản sao của 'Bar', với' virtual' lớp dẫn xuất nhất sẽ chỉ có một bản sao của 'Bar'. –
Thử: [tìm kiếm này] (http://stackoverflow.com/search?q = virtual + inheritance +% 5Bc% 2B% 2B% 5D) –
có thể trùng lặp của [In C++ virtual base class?] (http://stackoverflow.com/questions/21558/in-c-virtual-base-class) –