mardi 15 avril 2014

C++ hériter de plusieurs classes de base avec le même nom de fonction virtuelle - Stack Overflow


I tried this code:


class A
{
virtual void foo() = 0;
};

class B
{
virtual void foo() = 0;
};

class C : public A, public B
{
//virtual void A::foo(){}
//virtual void B::foo(){}

virtual void A::foo();
virtual void B::foo();
};

void C::A::foo(){}
void C::B::foo(){}

int main()
{
C c;
return 0;
}

It is OK when using the commented part, but when I try to write the definitions outside the class declaration, the compiler reports errors. I am using the MSVC11 compiler, does anyone know how to write this? I need to move the code into the cpp file.


Thank you~~




A function overrides a virtual function of a base class based on the name and parameter types (see below). Therefore, your class C has two virtual functions foo, one inherited from each A and B. But a function void C::foo() overrides both:


[class.virtual]/2



If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.



As I already stated in the comments, [dcl.meaning]/1 forbids the use of a qualified-id in the declaration of a (member) function:



When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers [...]"



Therefore any virtual void X::foo(); is illegal as a declaration inside C.


class C : public A, public B
{
virtual void foo();
};

Is the only way AFAIK to override foo, and it will override both A::foo and B::foo. There is no way to have to different overrides for A::foo and B::foo with different behaviour other than by introducing another layer of inheritance:


#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();
}



You've got just one virtual function foo:


class A {
virtual void foo() = 0;
};

class B {
virtual void foo() = 0;
};

class C : public A, public B {
virtual void foo();

};

void C::foo(){}
void C::A::foo(){}
void C::B::foo(){};

int main() {
C c;
return 0;
}


I tried this code:


class A
{
virtual void foo() = 0;
};

class B
{
virtual void foo() = 0;
};

class C : public A, public B
{
//virtual void A::foo(){}
//virtual void B::foo(){}

virtual void A::foo();
virtual void B::foo();
};

void C::A::foo(){}
void C::B::foo(){}

int main()
{
C c;
return 0;
}

It is OK when using the commented part, but when I try to write the definitions outside the class declaration, the compiler reports errors. I am using the MSVC11 compiler, does anyone know how to write this? I need to move the code into the cpp file.


Thank you~~



A function overrides a virtual function of a base class based on the name and parameter types (see below). Therefore, your class C has two virtual functions foo, one inherited from each A and B. But a function void C::foo() overrides both:


[class.virtual]/2



If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.



As I already stated in the comments, [dcl.meaning]/1 forbids the use of a qualified-id in the declaration of a (member) function:



When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers [...]"



Therefore any virtual void X::foo(); is illegal as a declaration inside C.


class C : public A, public B
{
virtual void foo();
};

Is the only way AFAIK to override foo, and it will override both A::foo and B::foo. There is no way to have to different overrides for A::foo and B::foo with different behaviour other than by introducing another layer of inheritance:


#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();
}


You've got just one virtual function foo:


class A {
virtual void foo() = 0;
};

class B {
virtual void foo() = 0;
};

class C : public A, public B {
virtual void foo();

};

void C::foo(){}
void C::A::foo(){}
void C::B::foo(){};

int main() {
C c;
return 0;
}

Related Posts:

0 commentaires:

Enregistrer un commentaire