Private bases

Discussion in 'C++' started by Dave, Nov 18, 2003.

  1. Dave

    Dave Guest

    Hello all,

    Suppose that derived inherits privately from base. A base pointer may not
    be made to point at a derived object in this case. I understand that is
    exactly what is supposed to happen and I understand that this is explicitly
    dictated by the Standard.

    I'm trying to understand the diagnostic my compiler generates in this case
    though:

    'type cast' : conversion from 'derived *' to 'base *' exists, but is
    inaccessible

    Exactly WHAT is it that is inaccessible? A constructor? A destructor?
    Consider this case:

    class base {};
    class derived: private base {};

    There's nothing in either class to be inaccessible!!! Yet this diagnostic
    results. Again, I do understand that this *IS* proper behavior. I'm just
    trying to understand what underlying language mechanism is coming into play
    here to enforce this restriction which is, indeed, explicitly requried by
    the standard.

    Also, just want to let everyone know I'm not trying to solve a particular
    real-life problem here. This question is purely academic in nature, so
    there is no answer to the oft-asked question "What are you trying to do?".
    Just trying to learn, man!!!

    Thanks!
    Dave
     
    Dave, Nov 18, 2003
    #1
    1. Advertising

  2. ....
    >
    > Suppose that derived inherits privately from base. A base pointer may not
    > be made to point at a derived object in this case. I understand that is
    > exactly what is supposed to happen and I understand that this is

    explicitly
    > dictated by the Standard.
    >
    > I'm trying to understand the diagnostic my compiler generates in this case
    > though:
    >
    > 'type cast' : conversion from 'derived *' to 'base *' exists, but is
    > inaccessible
    >
    > Exactly WHAT is it that is inaccessible? A constructor? A destructor?
    > Consider this case:
    >

    ....

    I would guess that, in this diagnostic message, inaccessible == private
     
    Thomas Wintschel, Nov 18, 2003
    #2
    1. Advertising

  3. Dave wrote:
    > Hello all,
    >
    > Suppose that derived inherits privately from base. A base pointer may not
    > be made to point at a derived object in this case. I understand that is
    > exactly what is supposed to happen and I understand that this is explicitly
    > dictated by the Standard.
    >
    > I'm trying to understand the diagnostic my compiler generates in this case
    > though:
    >
    > 'type cast' : conversion from 'derived *' to 'base *' exists, but is
    > inaccessible
    >
    > Exactly WHAT is it that is inaccessible? A constructor? A destructor?
    > Consider this case:
    >
    > class base {};
    > class derived: private base {};


    This means that the only scope that has visibility into base is within
    the class "derived".

    theoretically you could write :

    class derived: private base
    {
    base * get_base() { return this };
    };

    A method in derived is able to convert it's pointer to a base.

    >
    > There's nothing in either class to be inaccessible!!!


    "private" inheritance means that only the deriving class has access to
    the base class.

    Yet this diagnostic
    > results. Again, I do understand that this *IS* proper behavior.


    That *IS* the proper behaviour because it is defined like this.

    I'm just
    > trying to understand what underlying language mechanism is coming into play
    > here to enforce this restriction which is, indeed, explicitly requried by
    > the standard.


    The reason "public", "protected" and "private" inheritance is to control
    how classes can be used (i.e. what is supposed to be part of the
    interface and what is part of the implementation).

    Suppose you had to create a class that made "widgets". Now, suppose we
    only wanted a very small interface (because your programmers just love
    to mess with everything just because it's there and make a mess of
    things) ... and suppose making "widgets" is very similar to making
    "foobars" and so you can inherit from foobars but you only want a small
    amount of the foobars interface exposed.

    So - after all this supposing - here is an example:

    class make_foobars
    {
    public:

    void check_maker();

    void make_stuff();

    void foobar_stuff();
    };


    class make_widgets : private make_foobars
    {
    public:

    using make_foobars::check_maker; // we really want check_maker

    void make_stuff();
    };

    int main()
    {
    make_widgets widget_maker;

    widget_maker.check_maker(); // calls foobar::check_maker()

    widget_maker.make_stuff(); // calls make_widgets::make_stuff()

    // widget_maker.foobar_stuff(); // Can't do this ... this is foobar.

    };

    There is another way to do this use pure abstract classes. Notw that
    this mechanism is very good for reducing the coupling between
    application, interface and implementation even in compiled versions of
    the implementation.


    // Header file (interface) ..........
    class make_widgets
    {
    public:

    virtual ~make_widgets() {};

    virtual void make_stuff() = 0;

    virtual void check_maker() = 0;

    protected :
    make_widgets() {};

    };

    make_widgets * new_widget_maker();
    // End header file ...........


    // Implementation (.cpp file) ...........
    class make_widgets_impl : public make_foobars, public make_widgets
    {

    void make_stuff();

    void check_maker()
    {
    make_foobars::check_maker();
    }

    };

    make_widgets * new_widget_maker()
    {
    return new make_widgets_impl;
    }

    // End of .cpp file

    // using widget maker (application).
    int main()
    {
    make_widgets * y = new_widget_maker();

    y->make_stuff();

    y->check_maker();

    delete y;
    }

    ..................

    In the example above - the implementation of make_widgets is completly
    hidden. There are NO dependantcies other than the ones in the interface
    between the implementation and the application.

    This is used by COM and various "plug-in" systems however it is also
    just good practice to define clearly what the "interface" is.
     
    Gianni Mariani, Nov 18, 2003
    #3
  4. Gianni Mariani wrote:
    > class make_foobars
    > {
    > public:
    >
    > void check_maker();
    >
    > void make_stuff();
    >
    > void foobar_stuff();
    > };
    >
    >
    > class make_widgets : private make_foobars
    > {
    > public:
    >
    > using make_foobars::check_maker; // we really want check_maker
    >
    > void make_stuff();
    > };
    >


    again i see a lot of similarities between classes/structs and
    namespaces.. they must be strict cousins in the inner compiler
    representation...

    -----[ Domenico Andreoli, aka cavok
    --[ http://filibusta.crema.unimi.it/~cavok/gpgkey.asc
    ---[ 3A0F 2F80 F79C 678A 8936 4FEE 0677 9033 A20E BC50
     
    Domenico Andreoli, Nov 18, 2003
    #4
  5. Dave

    Ron Natalie Guest

    "Dave" <> wrote in message news:...

    > Exactly WHAT is it that is inaccessible? A constructor? A destructor?


    The whole class. The class is termed accessible if an arbitrary invented
    member would be accessible.

    Here base::foo() (if there were such a foo()) would not be accessible in derived,
    so the class "base" is not accessible.
     
    Ron Natalie, Nov 18, 2003
    #5
  6. Dave

    Chris Theis Guest

    "Domenico Andreoli" <> wrote in message
    news:9tnub.123704$...
    > Gianni Mariani wrote:
    > > class make_foobars
    > > {
    > > public:
    > >
    > > void check_maker();
    > >
    > > void make_stuff();
    > >
    > > void foobar_stuff();
    > > };
    > >
    > >
    > > class make_widgets : private make_foobars
    > > {
    > > public:
    > >
    > > using make_foobars::check_maker; // we really want check_maker
    > >
    > > void make_stuff();
    > > };
    > >

    >
    > again i see a lot of similarities between classes/structs and
    > namespaces.. they must be strict cousins in the inner compiler
    > representation...
    >


    Which seems reasonable, doesn't it? :)

    Chris
     
    Chris Theis, Nov 18, 2003
    #6
  7. Dave

    Dave Guest

    "Ron Natalie" <> wrote in message
    news:3fb9f081$0$164$...
    >
    > "Dave" <> wrote in message

    news:...
    >
    > > Exactly WHAT is it that is inaccessible? A constructor? A destructor?

    >
    > The whole class. The class is termed accessible if an arbitrary invented
    > member would be accessible.
    >
    > Here base::foo() (if there were such a foo()) would not be accessible in

    derived,
    > so the class "base" is not accessible.
    >
    >


    class base
    {
    public:
    void foo();
    };

    class derived: private base
    {
    };

    base::foo() *is* accessible inside of derived! The only case where it would
    not be is if it were private, but a private base member is never accessible
    in the derived class in *any* case!
     
    Dave, Nov 18, 2003
    #7
  8. Dave

    tom_usenet Guest

    On Mon, 17 Nov 2003 21:17:53 -0700, "Dave" <>
    wrote:

    >Hello all,
    >
    >Suppose that derived inherits privately from base. A base pointer may not
    >be made to point at a derived object in this case. I understand that is
    >exactly what is supposed to happen and I understand that this is explicitly
    >dictated by the Standard.
    >
    >I'm trying to understand the diagnostic my compiler generates in this case
    >though:
    >
    >'type cast' : conversion from 'derived *' to 'base *' exists, but is
    >inaccessible
    >
    >Exactly WHAT is it that is inaccessible? A constructor? A destructor?


    The conversion from derived* to base*, just as it says. That
    conversion is only accessible inside derived or using a c-style cast.
    I don't understand the question, given that you present the answer
    within the question...

    >Consider this case:
    >
    >class base {};
    >class derived: private base {};
    >
    >There's nothing in either class to be inaccessible!!! Yet this diagnostic
    >results. Again, I do understand that this *IS* proper behavior. I'm just
    >trying to understand what underlying language mechanism is coming into play
    >here to enforce this restriction which is, indeed, explicitly requried by
    >the standard.


    It's just that there is an implicit conversion from derived* to base*
    that is accessible globally if the inheritence is public, but only
    within derived if it is private.

    Tom
     
    tom_usenet, Nov 18, 2003
    #8
  9. Dave

    Mike Wahler Guest

    "Domenico Andreoli" <> wrote in message
    news:9tnub.123704$...

    > again i see a lot of similarities between classes/structs and
    > namespaces.. they must be strict cousins in the inner compiler
    > representation...


    Not necessarily, but they are indeed related, in that they
    all define a scope. A struct and a class are the same thing
    except that they have different default access.

    -Mike
     
    Mike Wahler, Nov 18, 2003
    #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. ! aaa
    Replies:
    1
    Views:
    1,117
    ! aaa
    May 28, 2004
  2. news

    Help with data bases

    news, Nov 14, 2003, in forum: HTML
    Replies:
    4
    Views:
    450
  3. Jim Fischer
    Replies:
    3
    Views:
    462
    Jim Fischer
    Jul 31, 2003
  4. Dave Theese

    Initialization of virtual bases

    Dave Theese, Aug 24, 2003, in forum: C++
    Replies:
    1
    Views:
    345
    John Harrison
    Aug 24, 2003
  5. ferran
    Replies:
    1
    Views:
    1,136
    Victor Bazarov
    Nov 28, 2003
Loading...

Share This Page