funkcja zastępuje funkcję wirtualną klasę bazową na podstawie nazwy i parametrów typów (patrz niżej) . W związku z tym klasa C
ma jedną wirtualną funkcję, jedną odziedziczoną po każdym A
i B
. Ale to funkcja void C::foo()
zastępuje zarówno:
[class.virtual]/2
Jeżeli wirtualne funkcja element vf
deklaruje klasą Base
w klasie Derived
, pochodzący, bezpośrednio lub pośrednio, z Base
, funkcja członkowska vf
o tej samej nazwie, listę parametrów typu, kwalifikację cv i kwalifikację ref (lub jej brak) jako Base::vf
jest zadeklarowana, następnie Derived::vf
jest również wirtualna (niezależnie od tego, czy jest to deklaracja, czy nie). ed) i to przesłaniaBase::vf
.
Jak już podano w komentarzach, [dcl.meaning]/1 zabrania zastosowanie kwalifikowanej ID w zgłoszeniu o (użytkownik) Funkcja:
Gdy declarator-id jest kwalifikowana, deklaracja odnosi się do wcześniej zadeklarowanej członek klasy lub przestrzeni nazw, do których odnosi się kwalifikator [...]”
Dlatego każdy virtual void X::foo();
jest illeg al jako deklaracja wewnątrz C
.
Kod
class C : public A, public B
{
virtual void foo();
};
jest jedynym sposobem AFAIK przesłonić foo
, i zastąpi on zarówno A::foo
i B::foo
. Nie ma sposobu, aby mieć dwa różne nadpisania dla A::foo
i B::foo
z różnych zachowań innych niż wprowadzając kolejną warstwę dziedziczenia:
#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();
}
skomentowane część jest również nie działa w gcc. –
To nie ma żadnego sensu. Powinno to być po prostu 'virtual void foo();' i just * once *. –
Jak chcesz _use_ 'A',' B' i 'C'? Istnieje wiele możliwości: [przykład 1] (http://ideone.com/KlVTgv), [przykład 2] (http: // ideone.com/R2SyTz), ... (prawdopodobnie określają więcej funkcji, niż to konieczne) –