I'm one of those people that has to get their code to compile with 0 warnings. Normally I respect the compiler and if it issues me a warning I take it as a sign that I should touch up my code a little. If I have to tell a compiler to ignore a given warning, I twitch a little.
But this one I can't seem to get around, and from what I can tell I haven't done anything "bad". Does anyone think that this is a poor design? I can't see anything particularly nasty about it (except for the "evil diamond") but it's perfectly valid and useful code. But it generates (in MSVC) a level 2 warning!
class IFoo
{
public:
virtual void foo() = 0;
};
class Bar : public virtual IFoo
{
public:
virtual void foo() { std::cout << "Hello, world!"; }
};
class Baz : public virtual IFoo
{
};
class Quux : public Bar, public Baz
{
};
Now if I create a Quux object it should be expected to call the Bar::foo implementation. MSVC is very helpful: it warns me for not being ambiguous enough?
warning C4250: 'Quux' : inherits 'Bar::Bar::foo' via dominance
Now I recognize I can turn this warning off with a pragma, but that's not the question I'm trying to ask here. Is there a reason I should be listening to the compiler here, or is this just an extremely overzealous warning?
When performing virtual inheritance, it is a bad idea to not explicitly override every member in the most derived class. Else, you are asking for your code to die a horrible death when someone changes one of your base classes that inherits from the virtual base. There's nothing actively wrong with this, your program won't crash or anysuch, but it's a maintainability bad idea. If you want to call the Bar::foo
version, then you should just delegate to it in Quux::foo
.
As far as the runability of your code is concerned, it is just there to remind you that Bar is the dominant implementation of foo
. It is just there to inform you, it's not really a warning, so that if you're debugging and think it's Baz
you don't pull your hair out :).
Is there a reason you aren't writing:
class Quux : public Bar, public Baz
{
using Bar::foo;
};
?
This gives you the same level of reuse, without the fragility.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With