Tôi đã trải qua điều này: - https://isocpp.org/wiki/faq/multiple-inheritance#mi-delegate-to-sisterĐoàn đến lớp chị em
Ai đó có thể cho tôi giải thích về điều này xảy ra như thế nào và tại sao điều này xảy ra?
Tôi đã trải qua điều này: - https://isocpp.org/wiki/faq/multiple-inheritance#mi-delegate-to-sisterĐoàn đến lớp chị em
Ai đó có thể cho tôi giải thích về điều này xảy ra như thế nào và tại sao điều này xảy ra?
Vì đây là các chức năng ảo và cuộc gọi là cuộc gọi đến chức năng từ bảng VirtualFunction. Nó chỉ là một tra cứu trong bảng theo chỉ mục được xác định. Bảng này nhận dữ liệu khi đối tượng được xây dựng và vì kiểu động của đối tượng là Tham gia và loại này có các mục nhập cho tất cả các hàm ảo, được kế thừa từ các lớp cơ sở.
Câu trả lời ngắn gọn là:
Mặc dù lớp Tham gia có nguồn gốc từ Der1 và Der2, sẽ chỉ có một phiên bản của lớp Cơ sở. Đó là vì thừa kế ảo. Nếu lớp cơ sở không phải là lớp trừu tượng và nếu bạn phải chuyển một số đối số cho hàm tạo, thì các cuộc gọi này sẽ bị bỏ qua trong cả hai, Der1 và Der2 và bạn sẽ phải vượt qua các đối số này thông qua Tham gia.
Khóa, thiếu trong hai câu trả lời khác là có thừa kế ảo tại chỗ. Điều này có nghĩa là trong đối tượng hoàn chỉnh chỉ có mộtBase
subobject, được chia sẻ bởi Der1
và Der2
.
Mỗi một trong những Der1
và Der2
loại cung cấp việc thực hiện một trong những chức năng ảo của cơ sở đó, và vì chỉ có một đối tượng như vậy, sự kết hợp của Der1
và Der2
cung cấp việc thực hiện cả thành viên bên trong đối tượng hoàn chỉnh.
Bạn có thể gửi đến lớp anh chị như bạn đang thực sự gọi chức năng thành viên của loại Base
và chức năng đó được thực hiện trong lớp phụ Base
của bạn (bằng lớp anh chị em của bạn). Lưu ý rằng Der1
không gọi Der2::bar
, nhưng thay vào đó là Base::bar
, sau đó được gửi đến người ghi đè cuối cùng xảy ra ở Der2
. Đây thực sự là không khác biệt so với công văn đến overrider cuối cùng trong các trường hợp khác:
struct base { virtual void f() = 0; };
struct d : base { void g() { f(); } };
struct d1 : d { void f() { std::cout << "here"; };
int main() {
d1 x;
x.g(); // dispatches from 'd::g' to 'd1::f' which is below in the hierarchy!
// yeah, right, everyone knows that... no magic here
}
Bây giờ nếu thừa kế không phải là ảo, sẽ có hai Base
subobjects trong các loại hoàn chỉnh, mỗi một trong số đó sẽ có một (khác) chức năng ảo thuần túy và thậm chí bạn sẽ không thể khởi tạo một đối tượng thuộc loại có nguồn gốc cao nhất (trừ khi điều đó cung cấp các định nghĩa cho các chức năng ảo)