Cannot access protected from base class?

Discussion in 'C++' started by Nephi Immortal, Sep 24, 2011.

  1. I discussed functionoids and pointer to member functions a long time
    ago. The template is the best option over functionoids because of the
    performance issue. Unfortunately, template does not support pointer
    to member function array.
    I am surprised to see that C++ Compiler reports an error to say any
    member function cannot access to protected from base class, but
    ordinary function worked. Very absurb?


    class Obj1
    {
    protected:
    static void Run1()
    {
    }

    void errRun1()
    {
    }
    };

    class Obj2
    {
    protected:
    static void Run2()
    {
    }

    void errRun2()
    {
    }
    };

    class Obj3
    {
    protected:
    static void Run3()
    {
    }

    void errRun3()
    {
    }
    };

    class Obj :
    public Obj1,
    public Obj2,
    public Obj3
    {
    public:
    void Run( int index )
    {
    static void ( * const pRun[ 3 ] )() =
    {
    Run1,
    Run2,
    Run3
    };

    pRun[ index ]();
    }

    void errRun( int index )
    {
    static void ( Obj::* const pRun[ 3 ] )() =
    {
    &Obj1::errRun1,
    &Obj2::errRun2,
    &Obj3::errRun3
    };

    ( this->*pRun[ index ] )();
    }
    };


    int main()
    {
    Obj obj;

    obj.Run( 0 );
    obj.Run( 1 );
    obj.Run( 2 );

    obj.errRun( 0 );
    obj.errRun( 1 );
    obj.errRun( 2 );

    return 0;
    }

    Debug Win32 ------
    Main.cpp
    c:\my projects\main.cpp(315): error C2248: 'Obj1::errRun1' : cannot
    access protected member declared in class 'Obj1'
    c:\my projects\main.cpp(264) : see declaration of
    'Obj1::errRun1'
    c:\my projects\main.cpp(258) : see declaration of 'Obj1'
    c:\my projects\main.cpp(316): error C2248: 'Obj2::errRun2' : cannot
    access protected member declared in class 'Obj2'
    c:\my projects\main.cpp(276) : see declaration of
    'Obj2::errRun2'
    c:\my projects\main.cpp(270) : see declaration of 'Obj2'
    c:\my projects\main.cpp(318): error C2248: 'Obj3::errRun3' : cannot
    access protected member declared in class 'Obj3'
    c:\my projects\main.cpp(288) : see declaration of
    'Obj3::errRun3'
    c:\my projects\main.cpp(282) : see declaration of 'Obj3'
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped
    ==========

    Can you please answer my question? Can hundred of base classes or
    thousands of base classes be inherited into ONE derived class through
    multiple inheritance? The option is the best if derived class has the
    ability to create large pointer to member function array in order to
    create command object.
     
    Nephi Immortal, Sep 24, 2011
    #1
    1. Advertising

  2. On 9/24/11 5:03 PM, Nephi Immortal wrote:
    > I discussed functionoids and pointer to member functions a long time
    > ago. The template is the best option over functionoids because of the
    > performance issue. Unfortunately, template does not support pointer
    > to member function array.
    > I am surprised to see that C++ Compiler reports an error to say any
    > member function cannot access to protected from base class, but
    > ordinary function worked. Very absurb?
    >
    >


    A derived class can only access the protected parts of a base camp
    through the derived class, not directly from the base camp.

    In your example, rather than using Obj1::run, use Obj::run. since Obj
    has inherited them, it can access them there.

    I will also add that this structure seems awkward. While having a large
    number of base classes is allowed, it feels like inheritance is being
    forced in a place where it really doesn't fit.
     
    Richard Damon, Sep 25, 2011
    #2
    1. Advertising

  3. On Sep 24, 7:14 pm, Richard Damon <>
    wrote:
    > On 9/24/11 5:03 PM, Nephi Immortal wrote:
    >
    > >    I discussed functionoids and pointer to member functions a long time
    > > ago.  The template is the best option over functionoids because of the
    > > performance issue.  Unfortunately, template does not support pointer
    > > to member function array.
    > >    I am surprised to see that C++ Compiler reports an error to say any
    > > member function cannot access to protected from base class, but
    > > ordinary function worked.  Very absurb?

    >
    > A derived class can only access the protected parts of a base camp
    > through the derived class, not directly from the base camp.
    >
    > In your example, rather than using Obj1::run, use Obj::run. since Obj
    > has inherited them, it can access them there.
    >
    > I will also add that this structure seems awkward. While having a large
    > number of base classes is allowed, it feels like inheritance is being
    > forced in a place where it really doesn't fit.


    I understand, but I wonder if large number of base classes violate
    rule and needs to make sure if more memory is sufficient.
     
    Nephi Immortal, Sep 25, 2011
    #3
  4. On 9/24/11 8:24 PM, Nephi Immortal wrote:
    > On Sep 24, 7:14 pm, Richard Damon<>
    > wrote:
    >> On 9/24/11 5:03 PM, Nephi Immortal wrote:
    >>
    >>> I discussed functionoids and pointer to member functions a long time
    >>> ago. The template is the best option over functionoids because of the
    >>> performance issue. Unfortunately, template does not support pointer
    >>> to member function array.
    >>> I am surprised to see that C++ Compiler reports an error to say any
    >>> member function cannot access to protected from base class, but
    >>> ordinary function worked. Very absurb?

    >>
    >> A derived class can only access the protected parts of a base camp
    >> through the derived class, not directly from the base camp.
    >>
    >> In your example, rather than using Obj1::run, use Obj::run. since Obj
    >> has inherited them, it can access them there.
    >>
    >> I will also add that this structure seems awkward. While having a large
    >> number of base classes is allowed, it feels like inheritance is being
    >> forced in a place where it really doesn't fit.

    >
    > I understand, but I wonder if large number of base classes violate
    > rule and needs to make sure if more memory is sufficient.


    A large number of base classes do not violate an inherent rule in C++.
    You will likely end up with a large object, as it needs to store all the
    base class members within it. It is possible that this may cause you to
    run out of memory, it somewhat depends on how many copies of this object
    are created.

    I do think it is a sign of a problematical design.
     
    Richard Damon, Sep 25, 2011
    #4
  5. On Sep 24, 10:56 pm, Richard Damon <>
    wrote:
    > On 9/24/11 8:24 PM, Nephi Immortal wrote:
    >
    >
    >
    >
    >
    > > On Sep 24, 7:14 pm, Richard Damon<>
    > > wrote:
    > >> On 9/24/11 5:03 PM, Nephi Immortal wrote:

    >
    > >>>     I discussed functionoids and pointer to member functions a long time
    > >>> ago.  The template is the best option over functionoids because of the
    > >>> performance issue.  Unfortunately, template does not support pointer
    > >>> to member function array.
    > >>>     I am surprised to see that C++ Compiler reports an error to say any
    > >>> member function cannot access to protected from base class, but
    > >>> ordinary function worked.  Very absurb?

    >
    > >> A derived class can only access the protected parts of a base camp
    > >> through the derived class, not directly from the base camp.

    >
    > >> In your example, rather than using Obj1::run, use Obj::run. since Obj
    > >> has inherited them, it can access them there.

    >
    > >> I will also add that this structure seems awkward. While having a large
    > >> number of base classes is allowed, it feels like inheritance is being
    > >> forced in a place where it really doesn't fit.

    >
    > > I understand, but I wonder if large number of base classes violate
    > > rule and needs to make sure if more memory is sufficient.

    >
    > A large number of base classes do not violate an inherent rule in C++.
    > You will likely end up with a large object, as it needs to store all the
    > base class members within it. It is possible that this may cause you to
    > run out of memory, it somewhat depends on how many copies of this object
    > are created.
    >
    > I do think it is a sign of a problematical design.- Hide quoted text -
    >
    > - Show quoted text -


    I am aware of design flaw, but careful design is better. Large
    number of base classes into one derived class is the option to replace
    virtual functions because of the performance issue and template is not
    the option unless you want pointer to member function array.
    All member functions in each base class should be static. The
    derived class will allocate approximately 4K to 32K memory if memory
    contains derived class’ pointer and array of indirect pointers.
    You can always create many copies of derived objects, but static
    member functions are shared by derived objects. You create interface
    class. It includes one derived object definition in the class body.
    The client can select the number of objects before interface does the
    job to process the derived object such as command object.

    For example:

    class Interface
    {
    public:
    void Run( int index )
    {
    cmdList.Execute( index );
    }

    private:
    derivedObject cmdList;
    };


    If you think that it is design flaw, please demonstrate another
    option.
     
    Nephi Immortal, Sep 26, 2011
    #5
  6. Nephi Immortal

    Ian Collins Guest

    On 09/26/11 12:18 PM, Nephi Immortal wrote:
    > On Sep 24, 10:56 pm, Richard Damon<>
    > wrote:
    >> On 9/24/11 8:24 PM, Nephi Immortal wrote:
    >>
    >>> I understand, but I wonder if large number of base classes violate
    >>> rule and needs to make sure if more memory is sufficient.

    >>
    >> A large number of base classes do not violate an inherent rule in C++.
    >> You will likely end up with a large object, as it needs to store all the
    >> base class members within it. It is possible that this may cause you to
    >> run out of memory, it somewhat depends on how many copies of this object
    >> are created.
    >>
    >> I do think it is a sign of a problematical design.- Hide quoted text -
    >>
    >> - Show quoted text -

    >
    > I am aware of design flaw, but careful design is better. Large
    > number of base classes into one derived class is the option to replace
    > virtual functions because of the performance issue and template is not
    > the option unless you want pointer to member function array.


    What sort of a performance issue have you measured?

    What makes templates unsuitable? I don't understand the context of
    "unless you want pointer to member function array".

    > If you think that it is design flaw, please demonstrate another
    > option.


    Exactly what problem are you trying to solve?

    --
    Ian Collins
     
    Ian Collins, Sep 26, 2011
    #6
  7. On 9/25/11 7:18 PM, Nephi Immortal wrote:

    > I am aware of design flaw, but careful design is better. Large
    > number of base classes into one derived class is the option to replace
    > virtual functions because of the performance issue and template is not
    > the option unless you want pointer to member function array.
    > All member functions in each base class should be static. The
    > derived class will allocate approximately 4K to 32K memory if memory
    > contains derived class’ pointer and array of indirect pointers.
    > You can always create many copies of derived objects, but static
    > member functions are shared by derived objects. You create interface
    > class. It includes one derived object definition in the class body.
    > The client can select the number of objects before interface does the
    > job to process the derived object such as command object.
    >
    > For example:
    >
    > class Interface
    > {
    > public:
    > void Run( int index )
    > {
    > cmdList.Execute( index );
    > }
    >
    > private:
    > derivedObject cmdList;
    > };
    >
    >
    > If you think that it is design flaw, please demonstrate another
    > option.


    I am not sure where you think you are going to gain in performance. Your
    dispatch function is apt to be as slow if not slower than a virtual
    function call, and your arrays of function pointers about as big
    combined as the virtual tables. If the base classes don't contain state,
    than composing them into this one super object doesn't by you anything,
    and if they do, your derived class is going to be very large since it
    has all of them.
     
    Richard Damon, Sep 26, 2011
    #7
  8. On Sep 25, 9:38 pm, Richard Damon <>
    wrote:
    > On 9/25/11 7:18 PM, Nephi Immortal wrote:
    >
    >
    >
    >
    >
    > >    I am aware of design flaw, but careful design is better.  Large
    > > number of base classes into one derived class is the option to replace
    > > virtual functions because of the performance issue and template is not
    > > the option unless you want pointer to member function array.
    > >    All member functions in each base class should be static.  The
    > > derived class will allocate approximately 4K to 32K memory if memory
    > > contains derived class pointer and array of indirect pointers.
    > >    You can always create many copies of derived objects, but static
    > > member functions are shared by derived objects.  You create interface
    > > class.  It includes one derived object definition in the class body.
    > >    The client can select the number of objects before interface does the
    > > job to process the derived object such as command object.

    >
    > > For example:

    >
    > > class Interface
    > > {
    > > public:
    > >    void Run( int index )
    > >    {
    > >            cmdList.Execute( index );
    > >    }

    >
    > > private:
    > >    derivedObject cmdList;
    > > };

    >
    > >    If you think that it is design flaw, please demonstrate another
    > > option.

    >
    > I am not sure where you think you are going to gain in performance. Your
    > dispatch function is apt to be as slow if not slower than a virtual
    > function call, and your arrays of function pointers about as big
    > combined as the virtual tables. If the base classes don't contain state,
    > than composing them into this one super object doesn't by you anything,
    > and if they do, your derived class is going to be very large since it
    > has all of them.- Hide quoted text -
    >
    > - Show quoted text -


    If you look at pointer to member function in C++ FAQ Lite, you will
    understand that it talks about functionoids. It does say that if
    performance is an issue, go ahead and use template instead of virtual
    function.
    I clarify to say why I can’t use template because template does not
    support pointer to member function array, but only one pointer to
    member function is supported.

    For example:

    template< typename Obj, typename Fn >
    void Run( Obj *pObj, Fn pFn )
    {
    ( pObj->*pFn )();
    }

    If you use this function above, where is pointer to member function
    array? If it exists, you can only select one member function and put
    it into Run’s parameter list.
    You saw my previous code above. It has static pointer to member
    function array in derived class’ Run( int index ).
     
    Nephi Immortal, Sep 26, 2011
    #8
  9. On 9/25/11 11:42 PM, Nephi Immortal wrote:
    > On Sep 25, 9:38 pm, Richard Damon<>
    > wrote:
    >> On 9/25/11 7:18 PM, Nephi Immortal wrote:
    >>
    >>
    >>
    >>
    >>
    >>> I am aware of design flaw, but careful design is better. Large
    >>> number of base classes into one derived class is the option to replace
    >>> virtual functions because of the performance issue and template is not
    >>> the option unless you want pointer to member function array.
    >>> All member functions in each base class should be static. The
    >>> derived class will allocate approximately 4K to 32K memory if memory
    >>> contains derived class pointer and array of indirect pointers.
    >>> You can always create many copies of derived objects, but static
    >>> member functions are shared by derived objects. You create interface
    >>> class. It includes one derived object definition in the class body.
    >>> The client can select the number of objects before interface does the
    >>> job to process the derived object such as command object.

    >>
    >>> For example:

    >>
    >>> class Interface
    >>> {
    >>> public:
    >>> void Run( int index )
    >>> {
    >>> cmdList.Execute( index );
    >>> }

    >>
    >>> private:
    >>> derivedObject cmdList;
    >>> };

    >>
    >>> If you think that it is design flaw, please demonstrate another
    >>> option.

    >>
    >> I am not sure where you think you are going to gain in performance. Your
    >> dispatch function is apt to be as slow if not slower than a virtual
    >> function call, and your arrays of function pointers about as big
    >> combined as the virtual tables. If the base classes don't contain state,
    >> than composing them into this one super object doesn't by you anything,
    >> and if they do, your derived class is going to be very large since it
    >> has all of them.- Hide quoted text -
    >>
    >> - Show quoted text -

    >
    > If you look at pointer to member function in C++ FAQ Lite, you will
    > understand that it talks about functionoids. It does say that if
    > performance is an issue, go ahead and use template instead of virtual
    > function.
    > I clarify to say why I can’t use template because template does not
    > support pointer to member function array, but only one pointer to
    > member function is supported.
    >
    > For example:
    >
    > template< typename Obj, typename Fn>
    > void Run( Obj *pObj, Fn pFn )
    > {
    > ( pObj->*pFn )();
    > }
    >
    > If you use this function above, where is pointer to member function
    > array? If it exists, you can only select one member function and put
    > it into Run’s parameter list.
    > You saw my previous code above. It has static pointer to member
    > function array in derived class’ Run( int index ).



    The issue is that the gain you might get for using the template, you
    have lost by having to do the array lookup. I will also point out that
    you don't need the template at all in your design, all your functions
    can have the same type (pointer to member function of type derived), and
    all can take the same type of object, derived.

    I think you are also being confused on what the FAQ says, the
    improvement that the functionoid can gain over the function call is when
    the compiler can see at compile time the type info and thus expand the
    template inline, and thus remove the function call. If you know which
    function to call, calling it directly will of course be slightly faster
    than going through the dispatch table, but your program structure is
    explicitly denying this operation by making them protected. Unless there
    is something more to be done in the dispatch routine, there is no reason
    they need to be protected.

    I think that you need to step back from the design and rather than
    figure out which toys sound interesting to use, ask yourself what REALLY
    needs to be done (not HOW, but WHAT), and then look at the simplest way
    to achieve that.

    From what I have seen so far, all the objects being created so far are
    extraneous since they are holding no information, only disjoint pieces
    of code. If they do need to store state, does one client really need ALL
    of them present?

    You also talk about gaining performance, have you actually implemented
    the straight forward method and found that the calling overhead is a
    significant factor? The way you talk about the runctions "running
    commands" makes it sound like they do real work, which probably
    overshadows and slight inefficiencies in the calling.
     
    Richard Damon, Sep 26, 2011
    #9
    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. Andy Ward

    Access to protected base member

    Andy Ward, Jun 17, 2004, in forum: C++
    Replies:
    7
    Views:
    345
    Hunter Hou
    Jun 21, 2004
  2. Siemel Naran
    Replies:
    4
    Views:
    810
    Micah Cowan
    Jan 12, 2005
  3. Andy Lomax
    Replies:
    5
    Views:
    477
    John Carson
    Jun 30, 2005
  4. Alf P. Steinbach
    Replies:
    6
    Views:
    550
    John Carson
    Sep 3, 2005
  5. Replies:
    2
    Views:
    818
    Noah Roberts
    Jun 9, 2006
Loading...

Share This Page