CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 26
  1. #1
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Polymorphism violating private access modifier

    I'm surprised I haven't encountered this yet (or perhaps I have but somehow didn't notice):

    Code:
    #include <iostream>
    #include <vector>
    
    class Base
    {
    public:
        virtual bool Is_Mouse_Over() const = 0;
    };
    
    class A : public Base
    {
    public:
        virtual bool Is_Mouse_Over() const
        {
            std::cout << "A::Is_Mouse_Over" << std::endl;
            return true;
        }
    };
    
    class B : public Base
    {
    private:
        virtual bool Is_Mouse_Over() const
        {
            std::cout << "B::Is_Mouse_Over" << std::endl;
            return true;
        }
    };
    
    int main()
    {
        std::vector<Base*> objects;
        objects.push_back(new A());
        objects.push_back(new B());
    
        objects&#091;0&#093;->Is_Mouse_Over();
        objects&#091;1&#093;->Is_Mouse_Over();
    
        return 0;
    }
    Prints out:
    A::Is_Mouse_Over
    B::Is_Mouse_Over
    Doesn't this violate the private access modifier somehow?

    Cheers.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Polymorphism violating private access modifier

    hmm... but why would one override a method with public access to have private access in the first place?
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: Polymorphism violating private access modifier

    Quote Originally Posted by laserlight View Post
    hmm... but why would one override a method with public access to have private access in the first place?
    Because they suck at designing inheritance hierarchies.

    I have a GUI_Object base class and decided recently that I needed my Text class to derive from it. However, the Text class shouldn't have some functions that the GUI_Object class declares.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Polymorphism violating private access modifier

    Quote Originally Posted by Mybowlcut
    I have a GUI_Object base class and decided recently that I needed my Text class to derive from it. However, the Text class shouldn't have some functions that the GUI_Object class declares.
    If the Text class should not have the public interface of the GUI_Object class in its entirety, then a Text object is not a GUI_Object, so you should not use public inheritance. Maybe you should use composition or private inheritance instead.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    Join Date
    Feb 2009
    Posts
    326

    Re: Polymorphism violating private access modifier

    It certainly is an interesting observation, I hadn't encountered this one. Thanks for that.

    I am not saying what happened in this case is correct,
    but I am explaining why it happened. (correct me if i am wrong):
    --------------------------------------------------------------------------------------------------------------------

    This happens because of late binding. (Binding is done at runtime for virtual functions).

    So at compile time the compiler doesn't know the value contained in objects[0] and objects[1].
    The compiler simply assumes that it objects[0] and objects[1] point to an object of the class Base.

    Since the class Base does have the function as public, it lets it through.


    Just to check this, you could make the following function private:
    Code:
    Base :: Is_Mouse_Over() //Make this function private and all Is_Mouse_Over() functions 
                                           //of the inherited classes would be inaccessible
    If you make it private, then all the functions would be inaccessible. This is bcuz at compile time, the compiler assumes the objects[0] and objects[1] point to object of the class Base.

    Again pls correct me if I am wrong.
    Last edited by Muthuveerappan; January 27th, 2010 at 07:23 AM.

  6. #6
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: Polymorphism violating private access modifier

    Hi Mybowlcut, haven't seen you in a while
    Quote Originally Posted by Mybowlcut
    I'm surprised I haven't encountered this yet
    that's probablly because we wouldn't normally overide a public method with private access xD

    I'm not sure if access modifier inside the class also restricts the call mechanism in the vtable like it does for the calls made outside
    I suppose, if any does restricts, it's the access modifier on the deriviation list.

  7. #7
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: Polymorphism violating private access modifier

    Quote Originally Posted by laserlight View Post
    If the Text class should not have the public interface of the GUI_Object class in its entirety, then a Text object is not a GUI_Object, so you should not use public inheritance. Maybe you should use composition or private inheritance instead.
    The real reason that it came about was that I was creating a GUI builder, and I needed to have a function that could create an object that derived from GUI_Object based on a string parameter and return the object as a shared_ptr<GUI_Object>.

    Perhaps private inheritance is what I want if I want to be able to do what I mentioned above...

    Edit: Muthuveerappan, that's why I thought it was happening too.

    Hi potatoCode.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  8. #8
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: Polymorphism violating private access modifier

    Hello there Mybowlcut

    as awlays, it'd be nice to see if someone could confirm what the Standard has to say on this.

  9. #9
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Polymorphism violating private access modifier

    Quote Originally Posted by Mybowlcut
    The real reason that it came about was that I was creating a GUI builder, and I needed to have a function that could create an object that derived from GUI_Object based on a string parameter and return the object as a shared_ptr<GUI_Object>.
    So, what is wrong with allowing Text to have the full public interface of GUI_Object?

    Quote Originally Posted by Mybowlcut
    Perhaps private inheritance is what I want if I want to be able to do what I mentioned above...
    No, it would not: generally, private inheritance is used to inherit an implementation, not to allow for polymorphism.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  10. #10
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: Polymorphism violating private access modifier

    Quote Originally Posted by laserlight View Post
    So, what is wrong with allowing Text to have the full public interface of GUI_Object?


    No, it would not: generally, private inheritance is used to inherit an implementation, not to allow for polymorphism.
    Here is my GUI_Object class:
    Code:
    class GUI_Object;
    
    typedef boost::shared_ptr<GUI_Object> gui_object_ptr;
    typedef boost::weak_ptr<GUI_Object> weak_gui_object_ptr;
    
    class Screen_Event;
    
    // The base of all GUI objects.
    class GUI_Object
    : public Named
    , public Renderable
    , public Event_Updateable
    , public boost::enable_shared_from_this<GUI_Object>
    {
    public:
        GUI_Object();
        GUI_Object(const std::string& name, weak_gui_object_ptr parent,
            bool visible, const PointI& position, const PointI& size, bool blocks, ushort depth);
        virtual ~GUI_Object() = 0;
    
        GUI_Object& operator=(const GUI_Object& rhs);
    
        virtual bool Is_Visible() const;
        virtual void Set_Visible(bool visible);
        virtual const PointI Get_Position() const;
        // Returns the absolute position of this object if it has a parent.
        // If there is no parent, return value is equal to Get_Position().
        virtual PointI Get_Absolute_Position() const;
        virtual void Set_Position(const PointI& position);
        virtual const PointI Get_Size() const;
        virtual void Set_Size(const PointI& size);
        ushort Get_Depth() const;
        virtual void Set_Depth(ushort depth);
        bool Blocks() const;
        bool Has_Parent() const;
        weak_gui_object_ptr Get_Parent();
        void Set_Parent(weak_gui_object_ptr parent);
    
        // If reading a GUI_Object from xml, we need a way to determine it's parent (if any).
        // The easiest way to do this is from within code, from an already constructed object.
      virtual void Read(ticpp::Element* element, weak_gui_object_ptr parent = weak_gui_object_ptr()) = 0;
        // Whilst most classes derived from GUI_Object do not need to be written,
        // there are some that do, thus all must be able to.
        virtual void Write(ticpp::Element* element) const = 0;
    
        virtual bool Is_Mouse_Over(const PointI& mouse) const = 0;
    
        virtual bool Blocks_Mouse(const PointI& mouse, ushort source_depth) const;
    
        // Returns true if this has the current focus.
        virtual bool Has_Focus() const = 0;
    protected:
        bool visible;
        PointI position;
        PointI size;
        bool blocks;
        ushort depth;
        weak_gui_object_ptr parent;
    };
    Here is my Text class:
    Code:
    class Text
    : public GUI_Object
    {
    public:
        Text();
        Text(const std::string& text, const std::string& font_fn, const PointI& position,
            int font_size, const SDL_Colour& colour, QUALITY quality, Uint8 alpha, ushort depth);
        Text(const Text& rhs);
        virtual ~Text();
    
        Text& operator=(const Text& rhs);
    
        virtual void Read(ticpp::Element* element, weak_gui_object_ptr parent = weak_gui_object_ptr());
        virtual void Write(ticpp::Element* element) const;
    
        using Renderable::Render;
        virtual void Render(SDL_Renderer& renderer);
        virtual void Render(SDL_Renderer& renderer, const PointI& position);
    
        virtual bool Is_Mouse_Over(const PointI& mouse) const;
    
        const std::string& Get_Text() const;
        void Set_Text(const std::string& text);
    
        template<typename T>
        void Set_Text(const T& t)
        {
            Set_Text(Conversions::to_string(t));
        }
    
        void Clear_Text();
    
        void Centre(const PointI& point);
        void Centre(int x_or_y, Direction::AXIS axis);
        void Centre(const PointI& position, const PointI& size);
        void Centre(int x_or_y, int w_or_h, Direction::AXIS axis);
    
        TTF_Font* Get_Font();
    
        const int Get_Font_Height() const;
        // Returns the surface size of this text.
        const PointI Get_Surface_Size() const;
        // Returns the surface size of text using this font.
        const PointI Get_Surface_Size(const std::string& text) const;
    
        // Returns the surface width of text using font.
        static const PointI Get_Surface_Size(TTF_Font* font, const std::string& text);
    protected:
        void Load_Font();
        virtual void Load_Text();
    
        std::string text, font_fn;
        int font_size;
        SDL_Colour colour;
        QUALITY quality;
        Uint8 alpha;
        TTF_Font* font;
        raw_surface_ptr surface;
    private:
        // Functions Text shouldn't expose.
        virtual const PointI Get_Size() const { return Get_Surface_Size(); }
        virtual void Set_Size(const PointI& size) {}
        virtual void Update(const SDL_Event* event_) {}
        virtual bool Blocks_Mouse(const PointI& mouse, ushort source_depth) const { return false; }
        virtual bool Has_Focus() const { return false; }
    };
    That shows which functions Text shouldn't have and hopefully my motives.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  11. #11
    Join Date
    May 2009
    Posts
    2,413

    Re: Polymorphism violating private access modifier

    Quote Originally Posted by Mybowlcut View Post
    Doesn't this violate the private access modifier somehow?
    No because you're accessing the object as a Base object.

    I often do this in polymorphic designs to enforce that derived type objects are used only as base type objects. Methods just aren't accessible in derived objects.

  12. #12
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: Polymorphism violating private access modifier

    Quote Originally Posted by nuzzle View Post
    No because you're accessing the object as a Base object.

    I often do this in polymorphic designs to enforce that derived type objects are used only as base type objects. Methods just aren't accessible in derived objects.
    How can they not be accessible considering my first post's sample code and output?
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  13. #13
    Join Date
    May 2009
    Posts
    2,413

    Re: Polymorphism violating private access modifier

    Quote Originally Posted by Mybowlcut View Post
    How can they not be accessible considering my first post's sample code and output?
    B* b = new B;
    Base* base = b; // upcast okay because a B type object is also a Base type object

    b->Is_Mouse_Over(); // compiler error because method is private in B
    base->Is_Mouse_Over(); // compiles okay because method is public in Base

    So access is determined by the type of the variable at compiletime.

    What method get's called is determined by the actual object type at runtime.
    Last edited by nuzzle; January 27th, 2010 at 08:16 AM.

  14. #14
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    1,569

    Re: Polymorphism violating private access modifier

    Quote Originally Posted by nuzzle View Post
    B* b = new B;
    Base* base = b; // upcast okay because a B type object is also a Base type object

    b->Is_Mouse_Over(); // compiler error because method is private in B
    base->Is_Mouse_Over(); // compiles okay because method is public in Base

    So access is determined by the type of the variable at compiletime.

    What method get's called is determined by the actual object type at runtime.
    Sorry, I understand that, but I still don't understand how you would enforce that a virtual function declared as private in a derived class but declared public in the base class is not called from a base class object such as the one in my example.

    This has brought up another problem for me... that is, I have a shared_ptr<GUI_Object> and want to have a property grid that displays the properties of the object - how would I get an instance of that type of object if all I have to go by is a string containing the type of the object? Can someone please suggest a better design? This one is horrible.
    Good judgment is gained from experience. Experience is gained from bad judgment.
    Cosy Little Game | SDL | GM script | VLD | Syntax Hlt | Can you help me with my homework assignment?

  15. #15
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: Polymorphism violating private access modifier

    Quote Originally Posted by Mybowlcut View Post
    Sorry, I understand that, but I still don't understand how you would enforce that a virtual function declared as private in a derived class but declared public in the base class is not called from a base class object such as the one in my example.
    You cannot enforce something that is in contrast to the mechanism you use. Public inheritance means is-a, so if you say that Text is a GUI_Object, then Text must behave like a GUI_Object. What you want to express is that Text is sort of a bit like a GUI_Object, which is not what public inheritance expresses.

    Besides, what would you expect to happen. The compiler does not (necessarily) know what's the derived object that you are calling the function on, so it cannot give you an error. Are you expecting a private_function_exception to be thrown?
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured