Derived methods hiding inherited methods

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tron Thomas

    #1

    Derived methods hiding inherited methods

    Under the right compiler the following code:

    class Base
    {
    public:
    virtual void Method(int){}
    };

    class Derived: public Base
    {
    public:
    virtual void Method(float){}
    };

    will produce a warning such as:

    'Derived::Metho d(float)' hides virtual function 'Base::Method(i nt)'

    This warning can be eliminated by adding the statement:

    using Base::Method;

    to the derived class.

    This issue with methods being hidden does not exist in other languages such as Java.
    What is the reason that derived methods can potentially hide base methods in C++?
  • Mike Wahler

    #2
    Re: Derived methods hiding inherited methods


    "Tron Thomas" <tron.thomas@ve rizon.net> wrote in message
    news:a4171f97.0 411081546.32a5e 466@posting.goo gle.com...[color=blue]
    > Under the right compiler the following code:
    >
    > class Base
    > {
    > public:
    > virtual void Method(int){}
    > };
    >
    > class Derived: public Base
    > {
    > public:
    > virtual void Method(float){}
    > };
    >
    > will produce a warning such as:
    >
    > 'Derived::Metho d(float)' hides virtual function 'Base::Method(i nt)'
    >
    > This warning can be eliminated by adding the statement:
    >
    > using Base::Method;
    >
    > to the derived class.
    >
    > This issue with methods being hidden does not exist in other languages[/color]
    such as Java.[color=blue]
    > What is the reason that derived methods can potentially hide base methods[/color]
    in C++?

    The C++ feature called "function overloading".

    -Mike


    Comment

    • andre dajd

      #3
      Re: Derived methods hiding inherited methods


      "Tron Thomas" <tron.thomas@ve rizon.net> wrote in message
      news:a4171f97.0 411081546.32a5e 466@posting.goo gle.com...[color=blue]
      > Under the right compiler the following code:
      >
      > class Base
      > {
      > public:
      > virtual void Method(int){}
      > };
      >
      > class Derived: public Base
      > {
      > public:
      > virtual void Method(float){}
      > };
      >
      > will produce a warning such as:
      >
      > 'Derived::Metho d(float)' hides virtual function 'Base::Method(i nt)'
      >
      > This warning can be eliminated by adding the statement:
      >
      > using Base::Method;
      >
      > to the derived class.[/color]

      Yes, that's how C++ works, methods are hidden by names, not by full type.
      The reason is purely practical. There is good explanation of why in
      Effective C++ (I think), but the basic idea is that in C++ you can have
      pretty complex inheritance patterns that could pull lots of overloaded
      functions with almost same argumnets in the single leaf class, not really
      "telling" the developer about it. He then can occasionally call a wrong
      function, not knowing about it's existence somewhere deeply in the
      inheritance lattice and then spend a lot of time debugging this problem

      And using "using" directive is exactlhy the prescribed solution. It was
      believed that to the developer explicitly pulling overloaded names that he
      needs to the child classes will cost him less than navigating the classes
      hierarchy in case of an error trying to identify what has gone wrong.
      [color=blue]
      >
      > This issue with methods being hidden does not exist in other languages
      > such as Java.[/color]

      That's because in Java all methods are virtual and there is no multiple
      inheritance, hence the abovementioned tradeoff did not appear relevant to
      Java designers.
      [color=blue]
      > What is the reason that derived methods can potentially hide base methods
      > in C++?[/color]

      Rgds
      d



      Posted Via Usenet.com Premium Usenet Newsgroup Services
      ----------------------------------------------------------
      ** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
      ----------------------------------------------------------
      Best Usenet Service Providers 2026 ranked by Newsgroup Access Newsservers, Usenet Search, Features & Free Trial. Add VPN for privacy.

      Comment

      • andre dajd

        #4
        Re: Derived methods hiding inherited methods


        "Mike Wahler" <mkwahler@mkwah ler.net> wrote in message
        news:jJTjd.2144 1$KJ6.19889@new sread1.news.pas .earthlink.net. ..[color=blue]
        >
        > "Tron Thomas" <tron.thomas@ve rizon.net> wrote in message
        > news:a4171f97.0 411081546.32a5e 466@posting.goo gle.com...[color=green]
        >> Under the right compiler the following code:
        >>[/color][/color]
        [][color=blue]
        >
        > The C++ feature called "function overloading".[/color]

        First, Java also has "function overloading". Second, "overloadin g" by
        itself never hides anything. "Overriding " can, but not applicable in the
        context.

        Rgds,
        d



        Posted Via Usenet.com Premium Usenet Newsgroup Services
        ----------------------------------------------------------
        ** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
        ----------------------------------------------------------
        Best Usenet Service Providers 2026 ranked by Newsgroup Access Newsservers, Usenet Search, Features & Free Trial. Add VPN for privacy.

        Comment

        • Gary Labowitz

          #5
          Re: Derived methods hiding inherited methods

          "andre dajd" <andre_dajd@hot mail.com> wrote in message
          news:41900a25$1 _1@127.0.0.1...[color=blue]
          >
          > "Tron Thomas" <tron.thomas@ve rizon.net> wrote in message
          > news:a4171f97.0 411081546.32a5e 466@posting.goo gle.com...[color=green]
          > > Under the right compiler the following code:
          > >
          > > class Base
          > > {
          > > public:
          > > virtual void Method(int){}
          > > };
          > >
          > > class Derived: public Base
          > > {
          > > public:
          > > virtual void Method(float){}
          > > };
          > >
          > > will produce a warning such as:
          > >
          > > 'Derived::Metho d(float)' hides virtual function 'Base::Method(i nt)'
          > >
          > > This warning can be eliminated by adding the statement:
          > >
          > > using Base::Method;
          > >
          > > to the derived class.[/color]
          >
          > Yes, that's how C++ works, methods are hidden by names, not by full type.
          > The reason is purely practical. There is good explanation of why in
          > Effective C++ (I think), but the basic idea is that in C++ you can have
          > pretty complex inheritance patterns that could pull lots of overloaded
          > functions with almost same argumnets in the single leaf class, not really
          > "telling" the developer about it. He then can occasionally call a wrong
          > function, not knowing about it's existence somewhere deeply in the
          > inheritance lattice and then spend a lot of time debugging this problem
          >
          > And using "using" directive is exactlhy the prescribed solution. It was
          > believed that to the developer explicitly pulling overloaded names that he
          > needs to the child classes will cost him less than navigating the classes
          > hierarchy in case of an error trying to identify what has gone wrong.
          >[color=green]
          > >
          > > This issue with methods being hidden does not exist in other languages
          > > such as Java.[/color]
          >
          > That's because in Java all methods are virtual and there is no multiple
          > inheritance, hence the abovementioned tradeoff did not appear relevant to
          > Java designers.[/color]

          Also note that in Java the two functions are considered different if their
          signatures are different, i.e. if the name plus the number and type of forma
          l parameters differ. In this case if you called Method on the derived class
          passing it an int (derived.Method (int)) you will run the inherited base
          class Method; if you call Method on the derived class passing it a float
          (derived.Method (float)) you will run the derived class Method. This is
          called method overloading. Java will not convert the int call to a float and
          call the derived class method. This is a major difference between C++ and
          Java.
          --
          Gary


          Comment

          • Andre Dajd

            #6
            Re: Derived methods hiding inherited methods

            "Gary Labowitz" <glabowitz@comc ast.net> wrote in message news:<J9-dnfliatKLrQ3cRV n-hA@comcast.com> ...[color=blue]
            > "andre dajd" <andre_dajd@hot mail.com> wrote in message
            > news:41900a25$1 _1@127.0.0.1...[color=green]
            > >
            > > "Tron Thomas" <tron.thomas@ve rizon.net> wrote in message
            > > news:a4171f97.0 411081546.32a5e 466@posting.goo gle.com...[color=darkred]
            > > > Under the right compiler the following code:[/color][/color][/color]
            [snip][color=blue][color=green][color=darkred]
            > > > This issue with methods being hidden does not exist in other languages
            > > > such as Java.[/color]
            > >
            > > That's because in Java all methods are virtual and there is no multiple
            > > inheritance, hence the abovementioned tradeoff did not appear relevant to
            > > Java designers.[/color]
            >
            > Also note that in Java the two functions are considered different if their
            > signatures are different, i.e. if the name plus the number and type of forma
            > l parameters differ.[/color]

            Same in C++.
            [color=blue]
            > In this case if you called Method on the derived class
            > passing it an int (derived.Method (int)) you will run the inherited base
            > class Method; if you call Method on the derived class passing it a float
            > (derived.Method (float)) you will run the derived class Method. This is
            > called method overloading.[/color]

            Again, same in C++, once you have brought the superclass' method into
            the scope of the child; there will be no ambiguity in C++. But the
            point here is different.

            Overloading a function always means having a collection of
            (different, obviousely) functions with same name, but different
            signatures. Methods are special case of functions and you can
            overload them by either extending a class or implementing several
            overloaded members in the same class.

            The only difference is what happens if you indeed overload a member in
            a child class. Java will always differentiate it from all overloads
            pulled from the superclass, overriding the one with same signature, if
            it were present in the superclass. C++ will do same, once
            specifically instructed by the developer by
            "using" directive. C++ simply does not do it automatically for the
            reasons I have already mentioned. Otherwise, the parent methods will
            be hidden. This does not mean that the superclass method and
            overriding method were considered "same". They are not same and
            that's why the compiler issues the warning reported in the root
            message. It's only the C++ default name resolution rule.
            [color=blue]
            >Java will not convert the int call to a float and
            > call the derived class method. This is a major difference between C++ and
            > Java.[/color]

            Well, yes, Java is more strict in automatic conversion, but this is
            not the point here. The point is that you may still bring several
            overloaded methods into a leaf class; in Java you will have to do
            repeated class inheritance while in C++ you can do it in one shot.
            Then, if in the leaf class you may find yourself calling (by mistake)
            a method from a superclass and then spend a lot of time figuring out
            what went wrong. Note, that you will have to do that anyway even if
            you do not overload a function in the child; you may still mix up the
            parent members.

            Apparently, this featuers comes from the time when nagivating thorugh
            the class hierarchy was quite a complex task, which it was in the
            absense of Javadoc or Doxygen or advanced IDEs, or anything else
            alike. So, this C++ feature simply warns the developer about a
            possible problem.

            d

            Comment

            • Tom Widmer

              #7
              Re: Derived methods hiding inherited methods

              On 8 Nov 2004 15:46:22 -0800, tron.thomas@ver izon.net (Tron Thomas)
              wrote:
              [color=blue]
              >Under the right compiler the following code:
              >
              >class Base
              >{
              >public:
              > virtual void Method(int){}
              >};
              >
              >class Derived: public Base
              >{
              >public:
              > virtual void Method(float){}
              >};
              >
              >will produce a warning such as:
              >
              >'Derived::Meth od(float)' hides virtual function 'Base::Method(i nt)'
              >
              >This warning can be eliminated by adding the statement:
              >
              >using Base::Method;
              >
              > to the derived class.
              >
              >This issue with methods being hidden does not exist in other languages such as Java.
              >What is the reason that derived methods can potentially hide base methods in C++?[/color]

              IIRC it's mainly to protect against the addition of new functions in
              base classes silently changing the meaning of code using derived
              classes. I suggest you read "The Design and Evolution of C++" by
              Stroustrup.

              Note that Java can be more dangerous than C++ to use for large scale
              software development (projects with millions of LOC) because it wasn't
              designed in such a way as to have changes in base classes have minimal
              silent impact on derived classes. In Java, adding a new base class
              function can silently change the meaning of code using a derived
              class; the base class author may know nothing at all about this
              derived class.

              Tom

              Comment

              • Tom Widmer

                #8
                Re: Derived methods hiding inherited methods

                On Tue, 9 Nov 2004 20:32:10 -0500, "Gary Labowitz"
                <glabowitz@comc ast.net> wrote:
                [color=blue]
                >"Pete Becker" <petebecker@acm .org> wrote in message
                >news:110004868 9.nyHvUOfTejjRM k1DxfFpjw@teran ews...[color=green]
                >> Gary Labowitz wrote:[color=darkred]
                >> >
                >> > I'd be interested in your explanation of this. If a new method is added[/color][/color]
                >to a[color=green][color=darkred]
                >> > base class, how does that affect a derived class that doesn't even know
                >> > about it? There are probably lots of people using derived classes[/color][/color]
                >(that's[color=green][color=darkred]
                >> > ALL of them in Java) that don't know the clone( ) method exists and[/color][/color]
                >don't[color=green][color=darkred]
                >> > care. If you see something here I don't I'd appreciate your giving an
                >> > example.[/color]
                >>
                >> struct Base
                >> {
                >> };
                >>
                >> struct Derived : Base
                >> {
                >> void f(int);
                >> };
                >>
                >> Derived d;
                >> d.f(3.0); // calls Derived::f(int) ;
                >>
                >> Now someone adds f(double) to Base, and d.f(3.0) no longer calls
                >> Derived::f(int) .[/color]
                >
                >Oh, I'm sorry, Peter. I thought the comment was about Java. I understand
                >this problem with C++. Thanks, though.[/color]

                The above was a demonstration of a problen that C++ *doesn't* have,
                but Java does. In the above in C++, d.f(3.0) always calls Derived::f,
                even if f(double) is added to Base, since Derived::f hides Base::f (if
                there is one). To clarify, here's the Java that demonstrates the
                problem:

                class Base
                {
                }

                class Derived extends Base
                {
                public void f(double d)
                {
                }
                }

                Derived d = new Derived();
                d.f(3);

                The above now calls Derived.f, but if you add f(int) to the base
                class, suddenly the meaning of that code will silently change.
                Basically the problem relates to name clashes between the method names
                of base classes and their derived classes.

                Tom

                Comment

                Working...