Virtual functions

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

    Virtual functions

    I was trying out the following sample code from Scotty Meyers:
    Effective C++ book:

    #include <iostream>

    class B {
    public:
    virtual void f() const { std::cout << "B::f()" << std::endl; }
    };

    class D : public B {
    public:
    virtual void f() { std::cout << "D::f()" << std::endl; }
    };

    int main()
    {
    D dx;
    B *pb = &dx;
    pb->f(); // will call B::f()
    return 0;
    }

    He says according to the standards this should be a compiler error but
    some compilers allow this to work. I found Visual Studio and g++ 3.2
    allow this.
    I would like to know if this is true, if not what maybe the philosophy
    behind allowing this ambigious behavior?
  • Victor Bazarov

    #2
    Re: Virtual functions

    paul wrote:
    I was trying out the following sample code from Scotty Meyers:
    Effective C++ book:
    >
    #include <iostream>
    >
    class B {
    public:
    virtual void f() const { std::cout << "B::f()" << std::endl; }
    };
    >
    class D : public B {
    public:
    virtual void f() { std::cout << "D::f()" << std::endl; }
    };
    >
    int main()
    {
    D dx;
    B *pb = &dx;
    pb->f(); // will call B::f()
    return 0;
    }
    >
    He says according to the standards this should be a compiler error
    Does he say which compiler error it should be? What item from his 50
    are you referring to?
    but
    some compilers allow this to work. I found Visual Studio and g++ 3.2
    allow this.
    I would like to know if this is true,
    If *what* is true?
    if not what maybe the philosophy
    behind allowing this ambigious behavior?
    In what way is this ambiguous?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask

    Comment

    • acehreli@gmail.com

      #3
      Re: Virtual functions

      On Jul 16, 11:56 am, paul <pradhan.push.. .@gmail.comwrot e:
      I was trying out the following sample code from Scotty Meyers:
      Effective C++ book:
      >
      #include <iostream>
      >
      class B {
      public:
              virtual void f() const { std::cout << "B::f()" << std::endl; }
      There is a 'const' on that line.
      >
      };
      >
      class D : public B {
      public:
              virtual void f() { std::cout << "D::f()" << std::endl; }
      No 'const' on that line. Two compilers warn about that "name hiding": g
      ++, and Comeau online test compiler.
      >
      };
      >
      int main()
      {
              D dx;
              B *pb = &dx;
              pb->f(); // will call B::f()
      B has only one f() and D does not override it, so B::f() should be
      called.
              return 0;
      >
      }
      >
      He says according to the standards this should be a compiler error but
      some compilers allow this to work.
      I can't see how it is a compiler error.
      I found Visual Studio and g++ 3.2
      allow this.
      I would like to know if this is true, if not what maybe the philosophy
      behind allowing this ambigious behavior?
      I think name hiding was introduced to prevent certain types of hard to
      detect errors. Without name hiding, a function in D might be in use
      today through automatic type conversions on its parameter(s); but
      then, introducing a function in B with the same name but with a better
      matching parameter(s) could silently start using that function
      instead, even though we're using D's interface. (Something like
      that... :) )

      Ali

      Comment

      • paul

        #4
        Re: Virtual functions

        On Jul 16, 12:02 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
        paul wrote:
        I was trying out the following sample code from Scotty Meyers:
        Effective C++ book:
        >
        #include <iostream>
        >
        class B {
        public:
           virtual void f() const { std::cout << "B::f()" << std::endl; }
        };
        >
        class D : public B {
        public:
           virtual void f() { std::cout << "D::f()" << std::endl; }
        };
        >
        int main()
        {
           D dx;
           B *pb = &dx;
           pb->f(); // will call B::f()
           return 0;
        }
        >
        He says according to the standards this should be a compiler error
        >
        Does he say which compiler error it should be?  What item from his 50
        are you referring to?
        Item 48: Pay attention to compiler warnings. Actually I read again and
        it doesn't say it's an error, just that some compilers will emit a
        warning about name hiding.
         but
        >
        some compilers allow this to work. I found Visual Studio and g++ 3.2
        allow this.
        I would like to know if this is true,
        >
        If *what* is true?
        I was confused, I read again and it says some compilers emit a warning
        about name hiding and others don't.
         if not what maybe the philosophy
        >
        behind allowing this ambigious behavior?
        >
        In what way is this ambiguous?
        I found this is as ambigious as having
        virtual void f(int x);
        virtual void f(char x);

        Comment

        • James Kanze

          #5
          Re: Virtual functions

          On Jul 17, 1:22 am, paul <pradhan.push.. .@gmail.comwrot e:
          On Jul 16, 12:02 pm, Victor Bazarov <v.Abaza...@com Acast.netwrote:
          paul wrote:
          I was trying out the following sample code from Scotty
          Meyers: Effective C++ book:
          First time I've heard him called Scotty:-).
          #include <iostream>
          class B {
          public:
          virtual void f() const { std::cout << "B::f()" << std::endl; }
          };
          class D : public B {
          public:
          virtual void f() { std::cout << "D::f()" << std::endl; }
          };
          int main()
          {
          D dx;
          B *pb = &dx;
          pb->f(); // will call B::f()
          return 0;
          }
          He says according to the standards this should be a
          compiler error
          Does he say which compiler error it should be? What item
          from his 50 are you referring to?
          Item 48: Pay attention to compiler warnings. Actually I read
          again and it doesn't say it's an error, just that some
          compilers will emit a warning about name hiding.
          Which is something completely different. There is no error in
          the code, at least with regards to the standard. There is,
          likely, an error with regards to what was wanted. Compilers are
          free to warn about anything they feel like; in this case, the
          warning is probably a good thing, since you probably meant to
          make the derived function const as well (so that it would
          override the function in the base class).
          but
          some compilers allow this to work. I found Visual Studio
          and g++ 3.2 allow this. I would like to know if this is
          true,
          If *what* is true?
          I was confused, I read again and it says some compilers emit a
          warning about name hiding and others don't.
          And it probably depends on the options with which you invoke the
          compiler. Try using -Woverloaded-virtual with g++, for example.
          (Don't know why this isn't included with -Wall, but it isn't.)
          if not what maybe the philosophy
          behind allowing this ambigious behavior?
          In what way is this ambiguous?
          I found this is as ambigious as having
          virtual void f(int x);
          virtual void f(char x);
          I think your confusing ambigious with some other word. There's
          not the slightest ambiguity here; the standard is clear as to
          what is required. (Note that ambiguous can easily have two
          different meanings in this context: the standard itself can be
          ambiguous, in which case, we can't determine exactly what is
          required; or a function call can be abiguous: the standard
          (clearly?) says that the call is ambiguous, and requires the
          compiler to issue a diagnostic. Neither applies here, however.)

          The rule is somewhat surprising here, but is necessary in its
          general form to prevent code from silently changing meaning when
          presumably unrelated code (e.g. the private section of a base
          class) evolves. It also turns out to be very coherent, working
          over classes in the same way it works inside functions, etc.
          Roughly speaking, when doing name lookup, the compiler
          estabishes an ordered list of scopes, and stops at the first one
          in which it finds the name.

          If I could change something here (but it's way too late), I'd
          require some sort of explicit statement as to 1) whether this
          declaration is meant to override something in the base class or
          not, and 2) whether the author wishes to allow this declaration
          to be overridden. Something like:

          void f() ;
          // overrides nothing, cannot be overridden
          overrides void f() ;
          // overrides a virtual function in a
          // base class, cannot be overridden
          virtual void f() ;
          // overrides nothing, but can be
          // overridden.
          overrides virtual void f() ;
          // overrides a virtual function in a
          // base class, and can be overriden in
          // a derived class.

          Name hiding would still work as it does now, but if you meant to
          override, and made a mistake in the signature, you would get a
          compiler error (and not just maybe a warning).

          --
          James Kanze (GABI Software) email:james.kan ze@gmail.com
          Conseils en informatique orientée objet/
          Beratung in objektorientier ter Datenverarbeitu ng
          9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

          Comment

          Working...