C++ Inheritance via dominance warning

17,820

Everything is absolutely valid. A compiler is allowed to warn about valid code, no problem here. You can try silencing the warning with a using declaration. If this doesn't work (probably due to an MSVC bug), silence it with a pragma.

Share:
17,820
Cem Kalyoncu
Author by

Cem Kalyoncu

PhD in computer science (computational intelligence, computer vision and image processing). I have been programming since I was a kid. It is both my passion, hobby and profession.

Updated on June 06, 2022

Comments

  • Cem Kalyoncu
    Cem Kalyoncu about 2 years

    I'm trying to implement a rather large object that implements many interfaces. Some of these interfaces are pure virtual. I may have a problem in diamond inheritance. Visual Studio is reporting a warning of C4250 ('class1' : inherits 'class2::member' via dominance). First of all these classes are inherited virtually as it should be. The following is the partial class design that causes this problem.

    A        B        C
     \      / \      /
      \    /   \    /
        AB       BC 
        |         |
        |        BC2
        |         |
         \        D: Implementation of B, C, BC, BC2
          \      /
            Big
    

    In this entire tree only D implements virtual methods, there is no other definition of the method in question. And all virtual methods of B is listed in warnings. If important, D is a complete class.

    I read this happens with Boost serialization and it is safe to disregard the warning.

    Is this method I am trying to achieve valid? Is it safe to disregard this warning?

    Note 1: This is not a duplicate of Visual Studio Compiler warning C4250 ('class1' : inherits 'class2::member' via dominance), I have tried the solution proposed there.

    Note 2: I can also send class diagram but its a little more complicated than this.

    EDIT: Full warning is as follows:

    warning C4250: 'gge::resource::ImageResource' : inherits 
    'gge::graphics::ImageTexture::gge::graphics::ImageTexture::drawin' 
    via dominance
    

    gge::resource::ImageResource is Big in the drawing, gge::graphics::ImageTexture is D, drawin is one of the six methods I get warning for.

    • hammar
      hammar almost 13 years
      Implementing many interfaces is a sign that your class may have too much responsibility. Consider refactoring it into several smaller classes.
    • Cem Kalyoncu
      Cem Kalyoncu almost 13 years
      @hammar: I tried but the problem is not about the class, Big is just an image but there are many interfaces to support many different type of graphics. Functions that require the services of a specific interface should use the smallest interface that satisfies their needs. As a sample, using these properties, I can substitute a particle system as a mouse pointer. In short I couldn't break into smaller classes.
    • Emile Cormier
      Emile Cormier almost 13 years
      Consider the Decoration pattern (en.wikipedia.org/wiki/Decorator_pattern) as an alternative to subclassing.
    • Cem Kalyoncu
      Cem Kalyoncu almost 13 years
      @emile: I read Decorator pattern, its more complicated compared to MI. This method compiles and runs fine but not sure if it will keep working. I have an alternative to create a variable of D and map public methods to it. But this design seems more natural.
    • Mark B
      Mark B almost 13 years
      Which classes specifically from your diagram are "class1" and "class2" in the message?
    • Cem Kalyoncu
      Cem Kalyoncu almost 13 years
      @mark: nmspc::Big inherits nmspc::D::nmspc::D::member, D is repeated twice if it means anything.
    • David Rodríguez - dribeas
      David Rodríguez - dribeas almost 13 years
      @Cem Kalyoncu: Can you post the exact (and complete) warning? Also identify in where in the drawing each one of the classes in the warning lies (i.e. nmspc::Big is Big in the diagram, nmspc::D is what?)
    • Cem Kalyoncu
      Cem Kalyoncu almost 13 years
      @David: D is right above big in the right side.
  • Cem Kalyoncu
    Cem Kalyoncu almost 13 years
    If using was working I was not going to ask the question, pragma should do the trick. Thanks for the answer.
  • n. m.
    n. m. almost 13 years
    I hear that for some people using works or fails depending on non-significant whitespace in the source file. If it's true, there's definitely a compiler bug there.
  • n. m.
    n. m. over 10 years
    @DeniseSkidmore: it should be using base::method; but it doesn't work with VC++ anyway, and other compilers don't need it.
  • Spencer
    Spencer over 4 years
    A using-declaration will not override inheritance by dominance, whatever compiler you use: godbolt.org/z/LtUAJU still returns 2.
  • n. m.
    n. m. over 4 years
    @Spencer the problem is not in overriding anything or changing how the feature works but in.silencing a fairly useless warning.
  • Spencer
    Spencer over 4 years
    It certainly boils down to suppressing the warning, but the "uselessness" of the warning is a matter of opinion. The using-declaration in the sample code I provided is ineffective and also misleading. Without the warning, the program would silently misbehave with no obvious reason.
  • n. m.
    n. m. over 4 years
    @Spencer There is one single implementation of the method in the class and all its base classes, which the programmer obviously wants to be used. I don't see what other intent could possibly be there.
  • Spencer
    Spencer over 4 years
    That's true In OP's case, but not in my sample code. My point is that using will never work.
  • Joachim Mairböck
    Joachim Mairböck over 4 years
    It seems that clang (at least version 9.0.0) disagrees here and the using B::f in the linked godbolt example changes the output. With the using it returns 1, without it returns 2, as gcc and MSVC.
  • n. m.
    n. m. over 4 years
    @JoachimMairböck This most definitely looks like a clang bug to me. Calling the function via A, B or C references to a D object results in the expected 1 being returned. Only calling through a D reference returns 2. But there should be a single final overrider.
  • MFH
    MFH over 4 years
    @n.'pronouns'm. If there is a bug, it is not limited to clang, as we have at least 3 different interpretations of this situation: godbolt.org/z/nX7Kbv
  • n. m.
    n. m. over 4 years
    @MFH I'm not surprised one little bit. This is a seldom-explored area of the language. This code should print 2 in every case (IMHO) as C::f is the final overrider.