×

Loading...
Ad by
  • 最优利率和cashback可以申请特批,好信用好收入offer更好。请点链接扫码加微信咨询,Scotiabank -- Nick Zhang 6478812600。
Ad by
  • 最优利率和cashback可以申请特批,好信用好收入offer更好。请点链接扫码加微信咨询,Scotiabank -- Nick Zhang 6478812600。

Here is the answer. ( exerpt from best selling C++ Primer version 4)

本文发表在 rolia.net 枫下论坛<b>Redefinition Hides Methods</b>
Suppose you create something like the following:


class Dwelling
{
public:
virtual void showperks(int a) const;
...
};
class Hovel : public Dwelling
{
{
public:
void showperks();
...
};

This causes a problem. You may get a compiler warning similar to the following:


Warning: Hovel::showperks(void) hides Dwelling::showperks(int)

Or perhaps you won't get a warning. Either way, the code has the following implications:


Hovel trump;
trump.showperks(); // valid
trump.showperks(5); // invalid

The new definition defines a showperks() that takes no arguments. Rather than resulting in two overloaded versions of the function, this redefinition hides the base class version that takes an int argument. In short, redefining inherited methods is not a variation of overloading. If you redefine a function in a derived class, it doesn't just override the base class declaration with the same function signature. Instead, it hides all base class methods of the same name, regardless of the argument signatures.

This fact of life leads to a couple of rules of thumb. First, if you redefine an inherited method, make sure you match the original prototype exactly. One exception is that a return type that is a reference or pointer to a base class can be replaced by a reference or pointer to the derived class. (This exception is new, and not all compilers recognize it yet. Also, note that this exception applies only to return values, not to arguments.) Second, if the base class declaration is overloaded, redefine all the base class versions in the derived class:


class Dwelling
{
public:
// three overloaded showperks()
virtual void showperks(int a) const;
virtual void showperks(double x) const;
virtual void showperks() const;
...
};
class Hovel : public Dwelling
{
public:
// three redefined showperks()
void showperks(int a) const;
void showperks(double x) const;
void showperks() const;
...
};

If you redefine just one version, the other two become hidden and cannot be used by objects of the derived class. Note that if no change is needed, the redefinition can simply call the base-class version.

Would you say <i>thank you</i> to me ?
;-)

BTW, I am not good at programming. Just curious to the question.
and know how to find answers.更多精彩文章及讨论,请光临枫下论坛 rolia.net
Report

Replies, comments and Discussions:

  • 工作学习 / IT技术讨论 / Visual C++ is stupid!
    本文发表在 rolia.net 枫下论坛Try the following program, the visual C++(6.0 and .net) do not let it be compiled.
    According to inheritance, overloading and overriding concepts,
    b->display(a1) should bind to the b_class::display(a1);
    b->play(a1) should bind to the b_class::play(a1); and
    b->play(a2) should bind to the b_class::play(a2).
    Do you agree?
    Can you run it by GNU C++?

    <pre>
    #include <iostream>
    using namespace std;
    class A
    {
    public:
    A(){x = 10, y =20;};
    int x,y;
    };
    class B: public A
    {
    public:
    B(){i = 10, j =20;};
    int i,j;
    };
    class b_class
    {public: virtual void display(A a)
    { cout<<"b_class, a= "<<a.x<<endl;
    }
    void play(A b)
    { cout<<"b_class, b = "<<b.y<<endl;
    }
    };
    class d_class : public b_class
    {public: void display(B f )
    { cout<<"d_class, f = "<<f.i<<endl;
    }
    void play(B g )
    { cout<<"d_class, g = "<<g.j<<endl;
    }
    };
    void main()
    { b_class *a;
    d_class *b, bo;
    a = new b_class();
    b = new d_class();
    A a1,a2;
    B b1,b2;
    a->display(a1);
    a->display(a2);
    b->display(a1);//error?
    a = b;
    a->display(b1);
    a->display(b2);
    a->play(a1);
    a->play(a2);
    b->play(a1);//error?
    b->play(a2);//error?
    }
    </pre>更多精彩文章及讨论,请光临枫下论坛 rolia.net
    • Inorder to calm your complains of M$ VC. I compiled it on SUN 880R using g++.
      t.cpp: In function `int main(...)':
      t.cpp:40: no matching function for call to `d_class::display (A &)'
      t.cpp:25: candidates are: void d_class::display(B)
      t.cpp:46: no matching function for call to `d_class::play (A &)'
      t.cpp:28: candidates are: void d_class::play(B)
      t.cpp:47: no matching function for call to `d_class::play (A &)'
      t.cpp:28: candidates are: void d_class::play(B)

      And I tried to change all your subs to use pointers.
      It still can not pass.
      t.cpp: In function `int main(...)':
      t.cpp:40: type `B' is not a base type for type `A'
      t.cpp:46: type `B' is not a base type for type `A'
      t.cpp:47: type `B' is not a base type for type `A'
    • Here is the answer. ( exerpt from best selling C++ Primer version 4)
      本文发表在 rolia.net 枫下论坛<b>Redefinition Hides Methods</b>
      Suppose you create something like the following:


      class Dwelling
      {
      public:
      virtual void showperks(int a) const;
      ...
      };
      class Hovel : public Dwelling
      {
      {
      public:
      void showperks();
      ...
      };

      This causes a problem. You may get a compiler warning similar to the following:


      Warning: Hovel::showperks(void) hides Dwelling::showperks(int)

      Or perhaps you won't get a warning. Either way, the code has the following implications:


      Hovel trump;
      trump.showperks(); // valid
      trump.showperks(5); // invalid

      The new definition defines a showperks() that takes no arguments. Rather than resulting in two overloaded versions of the function, this redefinition hides the base class version that takes an int argument. In short, redefining inherited methods is not a variation of overloading. If you redefine a function in a derived class, it doesn't just override the base class declaration with the same function signature. Instead, it hides all base class methods of the same name, regardless of the argument signatures.

      This fact of life leads to a couple of rules of thumb. First, if you redefine an inherited method, make sure you match the original prototype exactly. One exception is that a return type that is a reference or pointer to a base class can be replaced by a reference or pointer to the derived class. (This exception is new, and not all compilers recognize it yet. Also, note that this exception applies only to return values, not to arguments.) Second, if the base class declaration is overloaded, redefine all the base class versions in the derived class:


      class Dwelling
      {
      public:
      // three overloaded showperks()
      virtual void showperks(int a) const;
      virtual void showperks(double x) const;
      virtual void showperks() const;
      ...
      };
      class Hovel : public Dwelling
      {
      public:
      // three redefined showperks()
      void showperks(int a) const;
      void showperks(double x) const;
      void showperks() const;
      ...
      };

      If you redefine just one version, the other two become hidden and cannot be used by objects of the derived class. Note that if no change is needed, the redefinition can simply call the base-class version.

      Would you say <i>thank you</i> to me ?
      ;-)

      BTW, I am not good at programming. Just curious to the question.
      and know how to find answers.更多精彩文章及讨论,请光临枫下论坛 rolia.net
      • Thanks for sharing! That's really a tricky part of virtual functions.
      • unbelievable. You must be good on programming. Otherwise, how come you answer a so concrete problem.
    • Here 3 reasons
      1,Override函数原型须和base class里的virtual function prototype 一致。
      2,函数o\Overloading须在same scope!!!!.
      3,class A cannot be casted to B implicitly
    • 还有,我相信没有哪个C++compiler能够通过,除非是中科院出的C++compiler.
    • Thank you guys, please read the emails of the creator of C++.
      本文发表在 rolia.net 枫下论坛>>>Dear Prof. Bjarne Stroustrup,
      >>>When teaching overloading and overriding of C++, I hope to use the program as
      >>follows.
      >>>But the Visual C++(6.0 and .net) do not let it be compiled.
      >>>>According to inheritance, overloading and overriding concepts,
      >>>-----------------------------
      >>>b->display(a1) should bind to the b_class::display(a1);
      >>>b->play(a1) should bind to the b_class::play(a1); and
      >>>b->play(a2) should bind to the b_class::play(a2).
      >>>---------------------------------
      >>>Do you agree with me?
      >
      >>No, b_class::display(B) does not override a_class::display(A) because thy
      don't
      >>have the same argument type.
      >>
      >>???????????????????????????
      >>
      >>You are right. b_class::display(B) does not override a_class::display(A)
      >because thy don't
      >>have the same argument type.
      >>
      >>But class d_class should inherits b_class::play(A) and b_class::display(A),
      >therefore the instance of d_class should understance the message display(A) and
      >play(A). Right?
      >>
      >
      >No. the play() and display() functions in the derived class hides the play()
      and
      >display() functions in the base class. There is no overloading across scopes.
      >See: http://www.research.att.com/~bs/bs_faq2.html#overloadderived
      >
      >>???????????????????????????
      >!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      >Thank you very much for your reply.
      >Yes. I know that the C++ compilers are designed with this idea.
      >But we might need to consider overriding. I remember that in C++, overriding is
      resolved by a function's signature that includes the function name, the argument
      types and the number of the arguments.
      >By signature, b_class::play(A) and d_class::play (B), also b_class::display(A)
      and d_class::display(B) are different funcitons, they should not be overriden,
      right?
      >"There is no overloading across scopes. " But the subclass and the base class
      should be in the same scope with the idea of inheritance, right?


      No. I don't think so. A base class and its derived class are separate scopes.
      There are problems with that notion, just as there are problems with the notion
      that all members of a class are in a single scope. C++ always supported the
      former notion: A base class and its derived class are separate scopes.


      >!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      >
      >>

      >>>#include <iostream>
      >>>using namespace std;
      >>>class A
      >>>{
      >>> public:
      >>> A(){x = 10, y =20;};
      >>> int x,y;
      >>>};
      >>>class B: public A
      >>>{
      >>>public:
      >>> B(){i = 10, j =20;};
      >>> int i,j;
      >>>};
      >>>class b_class
      >>>{public: virtual void display(A a)
      >>> { cout<<"b_class, a= "<<a.x<<endl;
      >>> }
      >>> void play(A b)
      >>> { cout<<"b_class, b = "<<b.y<<endl;
      >>> }
      >>>};
      >>>class d_class : public b_class
      >>>{public: void display(B f )
      >>> { cout<<"d_class, f = "<<f.i<<endl;
      >>> }
      >>> void play(B g )
      >>> { cout<<"d_class, g = "<<g.j<<endl;
      >>> }
      >>>};
      >>>void main()
      >>>{ b_class *a;
      >>> d_class *b, bo;
      >>> a = new b_class();
      >>> b = new d_class();
      >>> A a1,a2;
      >>> B b1,b2;
      >>> a->display(a1);
      >>> a->display(a2);
      >>> b->display(a1);//error?
      >>> a = b;
      >>> a->display(b1);
      >>> a->display(b2);
      >>> a->play(a1);
      >>> a->play(a2);
      >>> b->play(a1);//error?
      >>> b->play(a2);//error?
      >>>}
      >>
      >> - Bjarne
      >>Bjarne Stroustrup, http://www.research.att.com/~bs更多精彩文章及讨论,请光临枫下论坛 rolia.net
    • I think this a problem of C++ design, if you give me encouragement, I would like to write a essay to argue with the C++ creator.