简体   繁体   English

实现具有多重继承的纯虚函数

[英]Implementing pure virtual functions with multiple inheritance

Suppose there is this interface: 假设有此接口:

class A{  
 public:  
  virtual foo()=0;  
};

And a class B which implements this interface: 和一个实现此接口的类B

class B:public A{    
 public:   
  virtual foo(){} //Foo implemented by B   
}

Finally, a class C which has classes A and B as base classes: 最后,一个类C ,它具有类AB作为基类:

Class C : public A, public B {
};

My question is, there is a way to tell the compiler that the implementation for foo is the one from class B without doing an explicit call to B::foo() ? 我的问题是,有一种方法可以告诉编译器foo的实现是来自类B的实现,而无需对B::foo()进行显式调用?

As @BenVoigt pointed out in the comments, the below answer only works due to a bug in g++ (meaning it isn't guaranteed to keep working, and it definitely isn't portable). 正如@BenVoigt在评论中指出的那样,以下答案仅是由于g ++中的一个错误而有效(这意味着它不能保证继续工作,并且绝对不能移植)。 Thus, although it may do what you want if you use a particular (buggy) compiler, it isn't an option you should use. 因此,尽管使用特定的(编译器)编译器可以满足您的要求,但这不是您应该使用的选项。

Do use virtual inheritance though. 不过要使用虚拟继承


This isn't exactly the scenario that the code in the question implies, but the sentence 这不完全是问题中的代码所暗示的情况,而是句子

My question is, there is a way to tell the compiler that the implementation for foo is the one from class B without doing an explicit call to B::foo()? 我的问题是,有一种方法可以告诉编译器foo的实现是来自类B的实现,而无需对B :: foo()进行显式调用?

seems to be asking for syntax to distinguish between multiple base versions of a function without using the :: qualifier. 似乎要求语法来区分一个函数的多个基本版本,而不使用::限定符。

You can do this with the using directive: 您可以using指令执行此using

#include <iostream>
class A {
public:
A(){}
virtual void foo(){std::cout<<"A func";}
};

class B: virtual public A {
  public:
  B(){}
  virtual void foo(){std::cout<<"B func";}
};
class C:virtual public A, virtual public B {
    public:
    C(){}
    using A::foo; // tells the compiler which version to use
                   // could also say using B::foo, though this is unnecessary
};

int main() {
    C c;
    c.foo(); // prints "A func"
    return 0;
}

Of course, the code itself in the question doesn't require this at all, as the other answers have pointed out. 当然,正如其他答案所指出的那样,问题中的代码本身根本不需要这样做。

Just use virtual inheritance, so that the A subobject provided by B is the same object used in C . 只需使用虚拟继承,即可使B提供的A子对象与C使用的对象相同。

Or write class C : public B ... it will be implicitly usable as an A anyway, via the base class B . 或编写class C : public B ...仍然可以通过基类B隐式地用作A


Before the question was edited: 在编辑问题之前:

B::foo is not compatible with A::foo . B::fooA::foo不兼容。

The required signature is 所需的签名是

ReturnType /* missing from question */ foo(A* const this /* this parameter is implicit */);

But B::foo has the signature 但是B::foo有签名

ReturnType foo(B* const this);

An A* , which will be passed to the virtual function, is not a B* , which the implementation requires. 一个A* ,这将被传递到虚函数,是不是一个B* ,其实现需要。 If B inherited from A , then the compiler would generate B::foo to accept an A* const subobject and find the B* const this object from that subobject pointer. 如果B继承自A ,则编译器将生成B::foo以接受A* const subobject并从该子对象指针中找到B* const this对象的B* const this But B::foo has no knowledge of the relationship in C . 但是B::foo不了解C中的关系。

As you have the two base classes in your example (which might be a design issue/design smell, I'd review that) you have to explicitly call the implementation that you are after, be it A::foo() or B:foo() . 由于示例中有两个基类(可能是设计问题/设计异味,我会回顾一下),因此必须显式调用要执行的实现,无论是A::foo()还是B:foo()

If all B does is to provide the implementation of foo() I'd consider moving the implementation into A (you can provide an implementation for a pure virtual function) but even in this case you'd have to call it via its qualified name. 如果B只是提供foo()的实现,我会考虑将实现移到A中(您可以为纯虚函数提供实现),但是即使在这种情况下,也必须通过其限定名称来调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM