Overriding methods with lower permission

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • danil52@mail.ru

    Overriding methods with lower permission

    Hello there,
    I have the following code:

    class Base {
    public:
    virtual void f() {cout << "Base::f()" << endl;}
    virtual void f(int) {cout << "Base::f(in t)" << endl;}
    };


    class Derived : public Base {
    void f() {cout << "Derived::f ()" << endl;}
    };

    int main() {
    Base *ptr = new Derived();
    ptr->f();
    ptr->f(1);

    return 0;
    }

    As you can see, I overridden Base::f() from public, to private access
    permission. Being the Java guy that I am, I expected a compiler error.
    But to my surprise, the program ran fine, and called the private
    version? Is this a compiler bug (I use g++), or is the function
    explicitly converted to public? Thank you.
  • puzzlecracker

    #2
    Re: Overriding methods with lower permission

    On Jul 28, 1:53 pm, dani...@mail.ru wrote:
    Hello there,
    I have the following code:
    >
    class Base {
    public:
      virtual void f() {cout << "Base::f()" << endl;}
      virtual void f(int) {cout << "Base::f(in t)" << endl;}
    >
    };
    >
    class Derived : public Base {
      void f() {cout << "Derived::f ()" << endl;}
    >
    };
    >
    int main() {
      Base *ptr = new Derived();
      ptr->f();
      ptr->f(1);
    >
      return 0;
    >
    }
    >
    As you can see, I overridden Base::f() from public, to private access
    permission. Being the Java guy that I am, I expected a compiler error.
    But to my surprise, the program ran fine, and called the private
    version? Is this a compiler bug (I use g++), or is the function
    explicitly converted to public? Thank you.
    That's allowed in C++. However, you're not allowed to provide more
    accessibility than provided by super class, in other words making it a
    private member a public in subclass is prohibited under the current
    standard.

    Comment

    • Pete Becker

      #3
      Re: Overriding methods with lower permission

      On 2008-07-28 13:53:41 -0400, danil52@mail.ru said:
      >
      As you can see, I overridden Base::f() from public, to private access
      permission. Being the Java guy that I am, I expected a compiler error.
      Java creates many misapprehension s.
      But to my surprise, the program ran fine, and called the private
      version? Is this a compiler bug (I use g++), or is the function
      explicitly converted to public? Thank you.
      Neither. Base::f is public, and Derived::f is private, just like you
      said they should be. Access is checked statically. That is, ptr->f()
      can call f because f is public in Base. Try it with a pointer to
      Derived.

      --
      Pete
      Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
      Standard C++ Library Extensions: a Tutorial and Reference
      (www.petebecker.com/tr1book)

      Comment

      • Pete Becker

        #4
        Re: Overriding methods with lower permission

        On 2008-07-28 14:35:25 -0400, puzzlecracker <ironsel2000@gm ail.comsaid:
        On Jul 28, 1:53 pm, dani...@mail.ru wrote:
        >Hello there,
        >I have the following code:
        >>
        >class Base {
        >public:
        >  virtual void f() {cout << "Base::f()" << endl;}
        >  virtual void f(int) {cout << "Base::f(in t)" << endl;}
        >>
        >};
        >>
        >class Derived : public Base {
        >  void f() {cout << "Derived::f ()" << endl;}
        >>
        >};
        >>
        >int main() {
        >  Base *ptr = new Derived();
        >  ptr->f();
        >  ptr->f(1);
        >>
        >  return 0;
        >>
        >}
        >>
        >As you can see, I overridden Base::f() from public, to private access
        >permission. Being the Java guy that I am, I expected a compiler error.
        >But to my surprise, the program ran fine, and called the private
        >version? Is this a compiler bug (I use g++), or is the function
        >explicitly converted to public? Thank you.
        >
        That's allowed in C++. However, you're not allowed to provide more
        accessibility than provided by super class, in other words making it a
        private member a public in subclass is prohibited under the current
        standard.
        No, it's not. I think you're confusing this with the rule about using
        directives, which are not allowed to increase access.

        --
        Pete
        Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
        Standard C++ Library Extensions: a Tutorial and Reference
        (www.petebecker.com/tr1book)

        Comment

        • danil52@mail.ru

          #5
          Re: Overriding methods with lower permission

          On Jul 28, 2:37 pm, Pete Becker <p...@versatile coding.comwrote :
          On 2008-07-28 13:53:41 -0400, dani...@mail.ru said:
          >
          >
          >
          As you can see, I overridden Base::f() from public, to private access
          permission. Being the Java guy that I am, I expected a compiler error.
          >
          Java creates many misapprehension s.
          >
          But to my surprise, the program ran fine, and called the private
          version? Is this a compiler bug (I use g++), or is the function
          explicitly converted to public? Thank you.
          >
          Neither. Base::f is public, and Derived::f is private, just like you
          said they should be. Access is checked statically. That is, ptr->f()
          can call f because f is public in Base. Try it with a pointer to
          Derived.
          >
          --
            Pete
          Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
          Standard C++ Library Extensions: a Tutorial and Reference
          (www.petebecker.com/tr1book)
          Well, that's obvious, access is checked only at compile-time. Compiler
          would have no idea which object is being used at run-time. Using
          pointer to Derived would produce an error - as expected. I understand
          all of that.

          But the fact is - I am able to call a private function! Compiler lets
          me override the function and give it lower permissions, which,
          logically shouldn't happen (Java compiler would choke on that piece of
          code).

          Comment

          • Pete Becker

            #6
            Re: Overriding methods with lower permission

            On 2008-07-28 15:04:41 -0400, danil52@mail.ru said:
            >
            But the fact is - I am able to call a private function! Compiler lets
            me override the function and give it lower permissions, which,
            logically shouldn't happen (Java compiler would choke on that piece of
            code).
            Why shouldn't it happen? You said you wanted to override f, and you
            said you don't want outsiders to be able to call Derived::f directly.
            The two aren't inconsistent from a language perspective. If you don't
            want that, don't do it. <g.

            --
            Pete
            Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
            Standard C++ Library Extensions: a Tutorial and Reference
            (www.petebecker.com/tr1book)

            Comment

            • puzzlecracker

              #7
              Re: Overriding methods with lower permission

              On Jul 28, 2:42 pm, Pete Becker <p...@versatile coding.comwrote :
              On 2008-07-28 14:35:25 -0400, puzzlecracker <ironsel2...@gm ail.comsaid:
              >
              >
              >
              On Jul 28, 1:53 pm, dani...@mail.ru wrote:
              Hello there,
              I have the following code:
              >
              class Base {
              public:
                virtual void f() {cout << "Base::f()" << endl;}
                virtual void f(int) {cout << "Base::f(in t)" << endl;}
              >
              };
              >
              class Derived : public Base {
                void f() {cout << "Derived::f ()" << endl;}
              >
              };
              >
              int main() {
                Base *ptr = new Derived();
                ptr->f();
                ptr->f(1);
              >
                return 0;
              >
              }
              >
              As you can see, I overridden Base::f() from public, to private access
              permission. Being the Java guy that I am, I expected a compiler error.
              But to my surprise, the program ran fine, and called the private
              version? Is this a compiler bug (I use g++), or is the function
              explicitly converted to public? Thank you.
              >
              That's allowed in C++. However, you're not allowed to provide more
              accessibility than provided by super class, in other words making it a
              private member a public in subclass is prohibited under the current
              standard.
              >
              No, it's not. I think you're confusing this with the rule about using
              directives, which are not allowed to increase access.
              >
              --
                Pete
              Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
              Standard C++ Library Extensions: a Tutorial and Reference
              (www.petebecker.com/tr1book)
              Argh, I see. Actually I wasn't. Would you explain the rule about
              using
              directives?

              Thanks

              Comment

              • Pete Becker

                #8
                Re: Overriding methods with lower permission

                On 2008-07-28 16:55:48 -0400, puzzlecracker <ironsel2000@gm ail.comsaid:
                Would you explain the rule about
                using
                directives?
                >
                class Base
                {
                void f();
                public:
                void g();
                };

                class Derived: public Base
                {
                void f(int); // hides Base::f
                void g(int); // hides Base::g
                // make base version visible (ignore duplication):
                using Base::f; // OK: same access
                using Base::g; // OK: more restricted access
                protected:
                using Base::f; // error: less restricted access
                using Base::g; // OK: more restricted access
                public:
                using Base::f; // error: less restricted access
                using Base::g; // OK: same access
                };

                --
                Pete
                Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
                Standard C++ Library Extensions: a Tutorial and Reference
                (www.petebecker.com/tr1book)

                Comment

                • =?ISO-8859-1?Q?Marcel_M=FCller?=

                  #9
                  Re: Overriding methods with lower permission

                  Hi,

                  danil52@mail.ru schrieb:
                  >Neither. Base::f is public, and Derived::f is private, just like you
                  >said they should be. Access is checked statically. That is, ptr->f()
                  >can call f because f is public in Base. Try it with a pointer to
                  >Derived.
                  >
                  Well, that's obvious, access is checked only at compile-time. Compiler
                  would have no idea which object is being used at run-time. Using
                  pointer to Derived would produce an error - as expected. I understand
                  all of that.
                  >
                  But the fact is - I am able to call a private function! Compiler lets
                  me override the function and give it lower permissions, which,
                  logically shouldn't happen (Java compiler would choke on that piece of
                  code).
                  it is quite common that an implementation of an interface (in fact a
                  pure function) should not be called directly. The standard gives you a
                  chance to restrict this.


                  Marcel

                  Comment

                  • Gennaro Prota

                    #10
                    Re: Overriding methods with lower permission

                    Pete Becker wrote:
                    On 2008-07-28 16:55:48 -0400, puzzlecracker <ironsel2000@gm ail.comsaid:
                    >
                    >Would you explain the rule about
                    >using
                    >directives?
                    >>
                    >
                    class Base
                    {
                    void f();
                    public:
                    void g();
                    };
                    >
                    class Derived: public Base
                    {
                    void f(int); // hides Base::f
                    void g(int); // hides Base::g
                    // make base version visible (ignore duplication):
                    using Base::f; // OK: same access
                    using Base::g; // OK: more restricted access
                    protected:
                    using Base::f; // error: less restricted access
                    using Base::g; // OK: more restricted access
                    public:
                    using Base::f; // error: less restricted access
                    using Base::g; // OK: same access
                    };
                    Where did you get this from? First, f isn't accessible in Derived, and
                    that's an error. All the rest is OK; aren't using declarations (and
                    not "directives ") intended to allow what was previously made with
                    access declarations?

                    --
                    Gennaro Prota | <https://sourceforge.net/projects/breeze/>
                    Do you need expertise in C++? I'm available.

                    Comment

                    • blargg

                      #11
                      Re: Overriding methods with lower permission

                      In article
                      <4ede373f-e2b2-43a7-a7aa-0c32aba7ba55@y3 8g2000hsy.googl egroups.com>,
                      danil52@mail.ru wrote:
                      On Jul 28, 2:37=A0pm, Pete Becker <p...@versatile coding.comwrote :
                      On 2008-07-28 13:53:41 -0400, dani...@mail.ru said:
                      As you can see, I overridden Base::f() from public, to private access
                      permission. Being the Java guy that I am, I expected a compiler error.
                      >
                      But to my surprise, the program ran fine, and called the private
                      version? Is this a compiler bug (I use g++), or is the function
                      explicitly converted to public? Thank you.
                      Neither. Base::f is public, and Derived::f is private, just like you
                      said they should be. Access is checked statically. That is, ptr->f()
                      can call f because f is public in Base. Try it with a pointer to
                      Derived.
                      >
                      But the fact is - I am able to call a private function! Compiler lets
                      me override the function and give it lower permissions, which,
                      logically shouldn't happen (Java compiler would choke on that piece of
                      code).
                      C++ gives the programmer choice, Java makes many choices for him. The
                      important question in this case is whether the choice C++ gives in this
                      case might lead to undiagnosed errors. Personally I'd like an "override"
                      keyword that must be present on overrides, as described here:

                      Comment

                      • James Kanze

                        #12
                        Re: Overriding methods with lower permission

                        On Jul 28, 7:53 pm, dani...@mail.ru wrote:
                        I have the following code:
                        class Base {
                        public:
                        virtual void f() {cout << "Base::f()" << endl;}
                        virtual void f(int) {cout << "Base::f(in t)" << endl;}
                        };
                        class Derived : public Base {
                        void f() {cout << "Derived::f ()" << endl;}
                        };
                        int main() {
                        Base *ptr = new Derived();
                        ptr->f();
                        ptr->f(1);
                        return 0;
                        }
                        As you can see, I overridden Base::f() from public, to private
                        access permission. Being the Java guy that I am, I expected a
                        compiler error.
                        Are you sure? I always thought that in Java, private meant
                        private; that since Derived::f() was private, it had nothing to
                        do with Base::f() (except, of course, that its presence would
                        prevent you from overriding Base::f()). (But I'm far from
                        sure.)
                        But to my surprise, the program ran fine, and called the
                        private version? Is this a compiler bug (I use g++), or is the
                        function explicitly converted to public?
                        Not exactly. You're calling Base::f(), which is public. It's
                        not considered relevant to access control that the function
                        which actually gets executed is Derived::f(). (It can't be
                        since access control is fully resolved at compile time, and the
                        compiler can't know which function will actually get executed.)
                        In other words, access control is always applied to the static
                        type.

                        In general, it's probably not a good idea to tighten access
                        controls in the derived class, because it's confusing; client
                        code can still call the function through an interface to the
                        base. On the other hand, in certain rare cases, the opposite
                        might be appropriate: overriding a private virtual function with
                        a public function in the derived class.

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

                        • Pete Becker

                          #13
                          Re: Overriding methods with lower permission

                          On 2008-07-28 20:41:12 -0400, Gennaro Prota <gennaro/prota@yahoo.com said:
                          Pete Becker wrote:
                          >On 2008-07-28 16:55:48 -0400, puzzlecracker <ironsel2000@gm ail.comsaid:
                          >>
                          >>Would you explain the rule about
                          >>using
                          >>directives?
                          >>>
                          >>
                          >class Base
                          >{
                          >void f();
                          >public:
                          >void g();
                          >};
                          >>
                          >class Derived: public Base
                          >{
                          >void f(int); // hides Base::f
                          >void g(int); // hides Base::g
                          > // make base version visible (ignore duplication):
                          >using Base::f; // OK: same access
                          >using Base::g; // OK: more restricted access
                          >protected:
                          >using Base::f; // error: less restricted access
                          >using Base::g; // OK: more restricted access
                          >public:
                          >using Base::f; // error: less restricted access
                          >using Base::g; // OK: same access
                          >};
                          >
                          Where did you get this from? First, f isn't accessible in Derived, and
                          that's an error. All the rest is OK; aren't using declarations (and
                          not "directives ") intended to allow what was previously made with
                          access declarations?
                          Yup, hasty example. Sorry.

                          --
                          Pete
                          Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
                          Standard C++ Library Extensions: a Tutorial and Reference
                          (www.petebecker.com/tr1book)

                          Comment

                          Working...