mercredi 16 avril 2014

Multiple C++ et héritage virtuel - Stack Overflow


I'm trying to implement the following classes :


class  a {
public :
//...
f();
//...
};

class b : virtual public a {
public :
//...
f();
//...
}

class c : virtual public a {
public :
//...
f();
//...
}

class d : virtual public c {
public :
//...
f();
//...
}

class e : public b, public d {
public :
//...
}

but the compiler tells me that the request for the member function f() is ambiguous. I want 'e' to inherit from the f() version of 'd' (so the 'c' one) but the code compiles only if I redeclare f() in 'e'. Therefore, I can compile only if I code the 'e' constructor as follows :


e::e(...) : a(...), c(...), b(...), d(...)
{
}

Which seems illogical to me, since 'd' inherate from 'c' and 'b' would be constructed first.




e is inherited from b & d, so there's b version of f() and d version of f().


It is very logical that there's an ambiguity.


If you want class e to use d version of f(), there are two ways,



  1. call d::f() directly in the call

    instance_e.d::f(); //will call d::f().


  2. redeclare d::f() in e

    class e : public b, public d { public : using d::f; }



I don't get why you mention constructor here, the order of contruction has no influence to the function f().




It doesn't matter with the order of construction or declaration. If there are 2 base classes with the same method name, the compiler cannot tell which one you meant to call. In your case, you have an overridden version of f() in both class b and class d.


So make the call explicit. b::f(), or d::f().



I'm trying to implement the following classes :


class  a {
public :
//...
f();
//...
};

class b : virtual public a {
public :
//...
f();
//...
}

class c : virtual public a {
public :
//...
f();
//...
}

class d : virtual public c {
public :
//...
f();
//...
}

class e : public b, public d {
public :
//...
}

but the compiler tells me that the request for the member function f() is ambiguous. I want 'e' to inherit from the f() version of 'd' (so the 'c' one) but the code compiles only if I redeclare f() in 'e'. Therefore, I can compile only if I code the 'e' constructor as follows :


e::e(...) : a(...), c(...), b(...), d(...)
{
}

Which seems illogical to me, since 'd' inherate from 'c' and 'b' would be constructed first.



e is inherited from b & d, so there's b version of f() and d version of f().


It is very logical that there's an ambiguity.


If you want class e to use d version of f(), there are two ways,



  1. call d::f() directly in the call

    instance_e.d::f(); //will call d::f().


  2. redeclare d::f() in e

    class e : public b, public d { public : using d::f; }



I don't get why you mention constructor here, the order of contruction has no influence to the function f().



It doesn't matter with the order of construction or declaration. If there are 2 base classes with the same method name, the compiler cannot tell which one you meant to call. In your case, you have an overridden version of f() in both class b and class d.


So make the call explicit. b::f(), or d::f().


0 commentaires:

Enregistrer un commentaire