Derived methods hiding inherited methods

Discussion in 'C++' started by Tron Thomas, Nov 8, 2004.

  1. Tron Thomas

    Tron Thomas Guest

    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::Method(float)' hides virtual function 'Base::Method(int)'

    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++?
    Tron Thomas, Nov 8, 2004
    #1
    1. Advertising

  2. Tron Thomas

    Mike Wahler Guest

    "Tron Thomas" <> wrote in message
    news:...
    > 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::Method(float)' hides virtual function 'Base::Method(int)'
    >
    > 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++?

    The C++ feature called "function overloading".

    -Mike
    Mike Wahler, Nov 8, 2004
    #2
    1. Advertising

  3. Tron Thomas

    andre dajd Guest

    "Tron Thomas" <> wrote in message
    news:...
    > 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::Method(float)' hides virtual function 'Base::Method(int)'
    >
    > This warning can be eliminated by adding the statement:
    >
    > using Base::Method;
    >
    > to the derived class.


    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.

    >
    > This issue with methods being hidden does not exist in other languages
    > such as Java.


    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.

    > What is the reason that derived methods can potentially hide base methods
    > in C++?


    Rgds
    d



    Posted Via Usenet.com Premium Usenet Newsgroup Services
    ----------------------------------------------------------
    ** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
    ----------------------------------------------------------
    http://www.usenet.com
    andre dajd, Nov 9, 2004
    #3
  4. Tron Thomas

    andre dajd Guest

    "Mike Wahler" <> wrote in message
    news:jJTjd.21441$...
    >
    > "Tron Thomas" <> wrote in message
    > news:...
    >> Under the right compiler the following code:
    >>

    []
    >
    > The C++ feature called "function overloading".


    First, Java also has "function overloading". Second, "overloading" 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 **
    ----------------------------------------------------------
    http://www.usenet.com
    andre dajd, Nov 9, 2004
    #4
  5. "andre dajd" <> wrote in message
    news:41900a25$1_1@127.0.0.1...
    >
    > "Tron Thomas" <> wrote in message
    > news:...
    > > 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::Method(float)' hides virtual function 'Base::Method(int)'
    > >
    > > This warning can be eliminated by adding the statement:
    > >
    > > using Base::Method;
    > >
    > > to the derived class.

    >
    > 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.
    >
    > >
    > > This issue with methods being hidden does not exist in other languages
    > > such as Java.

    >
    > 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.


    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
    Gary Labowitz, Nov 9, 2004
    #5
  6. Tron Thomas

    Andre Dajd Guest

    "Gary Labowitz" <> wrote in message news:<>...
    > "andre dajd" <> wrote in message
    > news:41900a25$1_1@127.0.0.1...
    > >
    > > "Tron Thomas" <> wrote in message
    > > news:...
    > > > Under the right compiler the following code:

    [snip]
    > > > This issue with methods being hidden does not exist in other languages
    > > > such as Java.

    > >
    > > 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.

    >
    > 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.


    Same in C++.

    > 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.


    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.

    >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.


    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
    Andre Dajd, Nov 9, 2004
    #6
  7. Tron Thomas

    Tom Widmer Guest

    On 8 Nov 2004 15:46:22 -0800, (Tron Thomas)
    wrote:

    >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::Method(float)' hides virtual function 'Base::Method(int)'
    >
    >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++?


    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
    Tom Widmer, Nov 9, 2004
    #7
  8. "Tom Widmer" <> wrote in message
    news:...
    > On 8 Nov 2004 15:46:22 -0800, (Tron Thomas)
    > wrote:

    <<snip>>
    > 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.


    I'd be interested in your explanation of this. If a new method is added to a
    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 (that's
    ALL of them in Java) that don't know the clone( ) method exists and don't
    care. If you see something here I don't I'd appreciate your giving an
    example.
    --
    Gary
    Gary Labowitz, Nov 10, 2004
    #8
  9. Tron Thomas

    Pete Becker Guest

    Gary Labowitz wrote:
    >
    > I'd be interested in your explanation of this. If a new method is added to a
    > 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 (that's
    > ALL of them in Java) that don't know the clone( ) method exists and don't
    > care. If you see something here I don't I'd appreciate your giving an
    > example.


    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).

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
    Pete Becker, Nov 10, 2004
    #9
  10. "Pete Becker" <> wrote in message
    news:1100048689.nyHvUOfTejjRMk1DxfFpjw@teranews...
    > Gary Labowitz wrote:
    > >
    > > I'd be interested in your explanation of this. If a new method is added

    to a
    > > 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

    (that's
    > > ALL of them in Java) that don't know the clone( ) method exists and

    don't
    > > care. If you see something here I don't I'd appreciate your giving an
    > > example.

    >
    > 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).


    Oh, I'm sorry, Peter. I thought the comment was about Java. I understand
    this problem with C++. Thanks, though.
    --
    Gary
    Gary Labowitz, Nov 10, 2004
    #10
  11. Tron Thomas

    Tom Widmer Guest

    On Tue, 9 Nov 2004 20:32:10 -0500, "Gary Labowitz"
    <> wrote:

    >"Pete Becker" <> wrote in message
    >news:1100048689.nyHvUOfTejjRMk1DxfFpjw@teranews...
    >> Gary Labowitz wrote:
    >> >
    >> > I'd be interested in your explanation of this. If a new method is added

    >to a
    >> > 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

    >(that's
    >> > ALL of them in Java) that don't know the clone( ) method exists and

    >don't
    >> > care. If you see something here I don't I'd appreciate your giving an
    >> > example.

    >>
    >> 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).

    >
    >Oh, I'm sorry, Peter. I thought the comment was about Java. I understand
    >this problem with C++. Thanks, though.


    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
    Tom Widmer, Nov 10, 2004
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lauchlan M
    Replies:
    1
    Views:
    2,936
    S. Justin Gengo
    Aug 26, 2003
  2. Laurent

    Hiding Inherited Attributes

    Laurent, Dec 6, 2004, in forum: C++
    Replies:
    3
    Views:
    337
    Victor Bazarov
    Dec 6, 2004
  3. Replies:
    1
    Views:
    394
    myork
    May 23, 2007
  4. Replies:
    1
    Views:
    386
    Victor Bazarov
    May 23, 2007
  5. 7stud --
    Replies:
    11
    Views:
    405
    7stud --
    Nov 9, 2007
Loading...

Share This Page