John
John

Reputation: 789

Override virtual function of base classes, which do not share common interface

#include <iostream>
struct B1
{
    virtual void method()=0;
    virtual ~B1(){}
};

struct B2
{
    virtual void method()=0;
    virtual ~B2(){}
};

struct D: B1, B2
{
    virtual void method()
    {
        std::cout << "D::method\n";
    };
};

int main(int argc,char *argv[])
{
    D d;
    B1 &b1=d;
    B2 &b2=d;
    b1.method();
    b2.method();
    return 0;
}

Note, B1 and B2 do not share common interface.

Is it this legal? If yes - in which standard? C++98/03/11 ?

Both, msvc and gcc have compiled it OK.

Previously I thought, that I have to use some common interface for such case (possible virtual inheritence).

Does such situation have some special name?

How it works in details, please? Maybe some ISO references?

Upvotes: 13

Views: 6351

Answers (2)

cppanda
cppanda

Reputation: 1315

afaik this is legal in every standart. i'm not sure if it has it's own special name, but it is similar to the diamond problem .

if you override "virtual void method()" in D, then you override both the method in B1 and B2.

Edit:

to anwser why you do not have "two different independed inherited virtual functions in D: B1::method and B2::method":

when overriding a method, you can can only specify the function name, return type and parameters, but you can not add signature details about which one you inherit from when overriding.

imagine that it would be possible, then it could look something like this:

struct D: B1, B2
{
    virtual void B1::method()
    {
        std::cout << "D::method\n";
    };
    virtual void B2::method()
    {
        std::cout << "D::method\n";
    };
};

but seeing this, you can already say that there is no possibility to have something like that, because when calling

objectD.method()

you can not specify which one you are calling. so even if there was a way to overload both, there is still the problem of distinguishing on the function call.

EDIT: "can not specify which one you are calling." refers to, you can not specify whether you want to call a class D overload of B2::method or the B2 method itself. objectD.B2::method will always invoke the B2 (not overloaded) method (which in this case won't compile as B2 has no implementation)

Upvotes: 1

James McNellis
James McNellis

Reputation: 354969

Your code is well-formed: void D::method() overrides both void B1::method() and void B2::method().

The specification states (C++11 §10.3/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.

B1 declares a virtual member function void B1::method(). Class D is derived from B1 and it also declares a member function with the same name (method), the same parameter list (no parameters), the same cv-qualification (no qualification) and the same ref-qualifier (no qualification).

Therefore, void D::method() overrides void B1::method().

The same logic applies for void B2::method() (just substitute B2 for B1 in the above explanation), so void D::method() overrides both void B1::method() and void B2::method().

Upvotes: 7

Related Questions