Vấn đề ở bàn tay khó mô tả nên mã được đặt lên phía trước để rõ ràng hơn.Nhiều sự thừa kế Cuộc gọi ảo Sự mơ hồ
struct Base
{
int b;
virtual void foo(){cout << b << endl;}
Base(int x) : b(x){}
};
struct Derived1 : Base //not virtual
{
virtual void foo(){/*Derived2's code*/}
Derived1() : Base(1){}
};
struct Derived2 : Base //not virtual
{
virtual void foo(){/*Derived2's code*/}
Derived2() : Base(2){}
};
struct MultiInheritance : Derived1, Derived2
{
void bar1()
{
//needs to access Derived1's Base foo()
}
void bar2()
{
//needs to access Derived2's Base foo()
}
};
Giả sử rằng trong một số kịch bản kỳ lạ lạ, tôi sẽ muốn có một lớp cơ sở MultiInheritance
có hai lớp cơ sở Derived1
và Derived2
rằng có một chung phi ảo cơ sở lớp Base
.
Có hai Base
trong MultiInheritance
, làm cách nào để chỉ định lớp học nào Base
tôi muốn truy cập trong MultiInheritance
?
Đoạn mã trên dường như hoạt động tốt bằng cách truyền nhiều lần, nhưng tôi không chắc liệu đây có phải là hành vi được xác định hay không. Nếu nó được, làm thế nào là điều này được thực hiện bởi trình biên dịch để thực hiện các nhu cầu của đa hình? Một mặt tất cả các cuộc gọi virtual
tất cả các cuộc gọi sẽ kết quả trong cùng một bảng chức năng virtual
, nhưng mặt khác nếu nó sẽ không xuất ra các câu trả lời khác nhau.
EDIT
tôi muốn nhấn mạnh rằng Base
lớp bắt buộc phải được phi ảo
EDIT2
lời xin lỗi sâu, tôi nghiêm túc bóp méo bản thân mình. Mã trên được cập nhật tốt hơn phản ánh câu hỏi ban đầu của tôi.
Mà một trong những bạn xem xét các * đúng * 'Base'? Hoặc là câu hỏi của bạn làm thế nào để làm cho nó để chỉ có một 'Base'? – Barry
Phân tích của bạn là chính xác và trình biên dịch sẽ xây dựng một vtable chính xác phản ánh sự tồn tại của hai lớp cơ sở. Để tránh điều đó, bạn cần thừa kế ảo và cấu trúc vtable sẽ trở nên phức tạp hơn. –
Không có sự mơ hồ trong ví dụ của bạn, nó hoạt động chính xác như nó nên bởi cuốn sách. "Bảng ảo" là chi tiết triển khai. Không ai nói bất cứ nơi nào mà mỗi thực hiện phải có một vtbl cho mỗi lớp, hoặc rằng phải có một mục nhập cho mỗi chữ ký hàm trong mỗi vtable. Trong thực tế, rất có thể ít nhất một trong những điều trên là không chính xác cho bất kỳ triển khai nào sử dụng vtables. –