Một chức năng ghi đè một hàm ảo của một lớp cơ sở dựa trên tên và thông số các loại (xem dưới đây) . Do đó, lớp học của bạn C
có hai chức năng ảo foo
, một được kế thừa từ mỗi A
và B
. Nhưng một hàm void C::foo()
ghi đè cả:
[class.virtual]/2
Nếu một hàm thành viên ảo vf
được khai báo trong một lớp Base
và trong một lớp học Derived
, có nguồn gốc trực tiếp hoặc gián tiếp từ Base
, chức năng thành viên vf
có cùng tên, thông số-loại-danh sách, cv-qualification và ref-qualifier (hoặc vắng mặt) như Base::vf
được khai báo, sau đó Derived::vf
cũng là ảo (cho dù có khai báo hay không) ed) và nó ghi đèBase::vf
.
Như tôi đã nêu trong các ý kiến, [dcl.meaning]/1 cấm việc sử dụng một trình độ -id trong việc kê khai của một (thành viên) chức năng:
Khi declarator-id có đủ điều kiện, tuyên bố sẽ đề cập đến một thành viên khai báo trước của lớp hoặc namespace mà vòng loại đề cập [...]"
Do đó bất kỳ virtual void X::foo();
được illeg al như một tuyên bố bên trong C
.
Mã
class C : public A, public B
{
virtual void foo();
};
là cách duy nhất để ghi đè AFAIK foo
, và nó sẽ ghi đè lên cả A::foo
và B::foo
. Không có cách nào để có hai ghi đè khác nhau cho A::foo
và B::foo
với hành vi khác ngoài bằng cách giới thiệu một lớp thừa kế:
phần
#include <iostream>
struct A
{
virtual void foo() = 0;
};
struct B
{
virtual void foo() = 0;
};
struct CA : A
{
virtual void foo() { std::cout << "A" << std::endl; }
};
struct CB : B
{
virtual void foo() { std::cout << "B" << std::endl; }
};
struct C : CA, CB {};
int main() {
C c;
//c.foo(); // ambiguous
A& a = c;
a.foo();
B& b = c;
b.foo();
}
nhận xét cũng không hoạt động trong gcc. –
Điều đó không có ý nghĩa gì cả. Nó chỉ nên là 'virtual void foo();', và chỉ * một lần *. –
Bạn muốn _use_ 'A',' B' và 'C' như thế nào? Có nhiều khả năng: [ví dụ 1] (http://ideone.com/KlVTgv), [ví dụ 2] (http: // ideone.com/R2SyTz), ... (có thể xác định nhiều chức năng hơn mức cần thiết) –