C++从具有相同虚函数名的多个基类继承

wat*_*son 13 c++ virtual class function multiple-inheritance

我试过这段代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

使用注释部分时可以,但是当我尝试在类声明之外编写定义时,编译器会报告错误.我正在使用MSVC11编译器,有谁知道怎么写这个?我需要将代码移动到cpp文件中.

谢谢~~

dyp*_*dyp 21

函数根据名称和参数类型覆盖基类的虚函数(参见下文).因此,你的类C2个虚函数foo,分别来自继承AB.但是一个函数void C::foo()会覆盖两者:

[class.virtual]/2

如果虚拟成员函数vf在类Base和类中声明Derived,直接或间接地从具有相同名称Base的成员函数派生vf,参数类型列表,cv限定和ref-qualifier(或不存在相同)Base::vf声明,然后Derived::vf也是虚拟的(无论是否声明)并覆盖Base::vf.

正如我在评论中已经说过的那样,[dcl.meaning]/1禁止在(成员)函数的声明中使用qualified-id:

declarator-id被限定时,声明应引用先前声明的限定符引用的类或命名空间的成员[...]"

因此任何内容virtual void X::foo();都是非法的宣言C.

代码

class C : public A, public B
{
    virtual void foo();
};
Run Code Online (Sandbox Code Playgroud)

是AFAIK覆盖的唯一方式foo,它将覆盖两者A::fooB::foo.有没有办法有两个不同的覆盖了A::fooB::foo比通过引入继承的另一层不同的行为:

#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();
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,歧义可以明确解决:`cA::foo();` (3认同)
  • @CătălinaSîrbu 如果您显式编写“virtual”,或者它与任何基类中的 _virtual_ 函数具有相同的签名(名称、参数),则该函数是虚拟的。所以这里的大多数“virtual”关键字都是多余的。我在所有虚拟函数前面加上“virtual”——即使没有必要——以直接表明该函数是虚拟的。 (2认同)

Pau*_*ans 4

你只有一个虚函数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;
}
Run Code Online (Sandbox Code Playgroud)

  • *备注:* 定义 `void C::A::foo(){}` 和 `void C::B::foo(){}` 提供了纯虚函数 `A::foo` 的定义和`B::foo`,分别(并且不是必需的)。 (5认同)