is this inheritance construct legal?

Discussion in 'C++' started by petschy, Sep 14, 2006.

  1. petschy

    petschy Guest

    Hello,

    class A
    {
    protected:
    class B { };
    }

    class C : public A, public A::B
    {
    };

    this won't compile, gcc-3.3 and gcc-4.1 both give errors, complaining
    that A::B is not visible.
    However, since C inherits from A, it should access C's protected parts,
    including B, right?

    B is a utility class, which is intended to be used in some of A's
    descendants.
    I can work the above error around, I'm just curious wheter the
    compilers are right or me.

    Cheers, p
     
    petschy, Sep 14, 2006
    #1
    1. Advertising

  2. petschy wrote:
    > Hello,
    >
    > class A
    > {
    > protected:
    > class B { };
    > }
    >
    > class C : public A, public A::B
    > {
    > };
    >
    > this won't compile, gcc-3.3 and gcc-4.1 both give errors, complaining
    > that A::B is not visible.
    > However, since C inherits from A, it should access C's protected
    > parts, including B, right?


    No. The names of the base classes have to be visible and accessible in
    the scope where the class is being defined. You haven't opened the 'C'
    class' scope yet to allow access to 'A::B'.

    > B is a utility class, which is intended to be used in some of A's
    > descendants.
    > I can work the above error around, I'm just curious wheter the
    > compilers are right or me.


    The compilers are right.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 14, 2006
    #2
    1. Advertising

  3. Victor Bazarov wrote:
    > petschy wrote:
    >> Hello,
    >>
    >> class A
    >> {
    >> protected:
    >> class B { };
    >> }
    >>
    >> class C : public A, public A::B
    >> {
    >> };
    >>
    >> this won't compile, gcc-3.3 and gcc-4.1 both give errors, complaining
    >> that A::B is not visible.
    >> However, since C inherits from A, it should access C's protected
    >> parts, including B, right?

    >
    > No. The names of the base classes have to be visible and accessible in
    > the scope where the class is being defined. You haven't opened the 'C'
    > class' scope yet to allow access to 'A::B'.


    I would like to understand this, but I'm not understanding the
    explanation - could you rephrase the explanation?

    As I see it there is no reason to derive from A::B since B is already a
    part of A right?

    class A
    {
    protected:
    class B{};
    };

    class C : public A
    {
    };

    Then B would be a protected member of C right? No need to explicitly
    derive A::B


    >
    >> B is a utility class, which is intended to be used in some of A's
    >> descendants.
    >> I can work the above error around, I'm just curious wheter the
    >> compilers are right or me.

    >
    > The compilers are right.
    >
    > V


    Victor
     
    Morten V Pedersen, Sep 14, 2006
    #3
  4. petschy

    Ron Natalie Guest

    Morten V Pedersen wrote:
    > Victor Bazarov wrote:
    >> petschy wrote:
    >>> Hello,
    >>>
    >>> class A
    >>> {
    >>> protected:
    >>> class B { };
    >>> }
    >>>
    >>> class C : public A, public A::B
    >>> {
    >>> };
    >>>
    >>> this won't compile, gcc-3.3 and gcc-4.1 both give errors, complaining
    >>> that A::B is not visible.
    >>> However, since C inherits from A, it should access C's protected
    >>> parts, including B, right?

    >>
    >> No. The names of the base classes have to be visible and accessible in
    >> the scope where the class is being defined. You haven't opened the 'C'
    >> class' scope yet to allow access to 'A::B'.

    >
    > I would like to understand this, but I'm not understanding the
    > explanation - could you rephrase the explanation?
    >
    > As I see it there is no reason to derive from A::B since B is already a
    > part of A right?
    >

    It's not a subobject of A, it's just got it's type name defined there.

    > class A
    > {
    > protected:
    > class B{};
    > };
    >
    > class C : public A
    > {
    > };
    >
    > Then B would be a protected member of C right? No need to explicitly
    > derive A::B


    B is not any kind of member of A or B.
    >
     
    Ron Natalie, Sep 14, 2006
    #4
  5. Morten V Pedersen wrote:
    > Victor Bazarov wrote:
    >> petschy wrote:
    >>> Hello,
    >>>
    >>> class A
    >>> {
    >>> protected:
    >>> class B { };
    >>> }
    >>>
    >>> class C : public A, public A::B
    >>> {
    >>> };
    >>>
    >>> this won't compile, gcc-3.3 and gcc-4.1 both give errors,
    >>> complaining that A::B is not visible.
    >>> However, since C inherits from A, it should access C's protected
    >>> parts, including B, right?

    >>
    >> No. The names of the base classes have to be visible and accessible
    >> in the scope where the class is being defined. You haven't opened
    >> the 'C' class' scope yet to allow access to 'A::B'.

    >
    > I would like to understand this, but I'm not understanding the
    > explanation - could you rephrase the explanation?


    All base classes have to be visible and accessible (the compiler has
    to be able to find the name and your class is supposed to have access
    to it) in the scope of the class definition. IOW, the sheer fact that
    you derive from 'A' does not give you access to 'A's members in the
    list of the base classes of 'C'. Only *inside* 'C'. The list of the
    base classes is *not* inside 'C'.

    > As I see it there is no reason to derive from A::B since B is already
    > a part of A right?


    No, you're not allowed to derive from it because it's not accessible to
    you. The compiler does not validate your *reasons*. It only validates
    the correctness of the program.

    > class A
    > {
    > protected:
    > class B{};
    > };
    >
    > class C : public A
    > {
    > };
    >
    > Then B would be a protected member of C right?


    That's correct.

    > No need to explicitly
    > derive A::B


    That's up to you. Inheritance (derivation) and membership are two
    different things (they have different connotations and implications).

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 14, 2006
    #5
  6. Ron Natalie wrote:
    > Morten V Pedersen wrote:
    >> Victor Bazarov wrote:
    >>> petschy wrote:
    >>>> Hello,
    >>>>
    >>>> class A
    >>>> {
    >>>> protected:
    >>>> class B { };
    >>>> }
    >>>> [...]

    >
    > B is not any kind of member of A or B.


    'B' *is* a member of A. Moreover, 'B' *is* a member of 'A::B', as well.
    (and, inside 'A', 'B' is a member of 'B'). The name 'B' is defined in
    the scope of the class 'A', as well as inside its own scope. Please do
    not confuse 'data member' with 'member'.

    An instance of 'B' is not a member of an instance of 'A', of course.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 14, 2006
    #6
  7. petschy

    Nate Barney Guest

    Victor Bazarov wrote:
    >
    > 'B' *is* a member of A. Moreover, 'B' *is* a member of 'A::B', as well.


    So, every class is a member of itself?
     
    Nate Barney, Sep 14, 2006
    #7
  8. Nate Barney wrote:
    > Victor Bazarov wrote:
    >>
    >> 'B' *is* a member of A. Moreover, 'B' *is* a member of 'A::B', as
    >> well.

    >
    > So, every class is a member of itself?


    Its name is. I am not sure about the rationale behind it, but the
    name of every class is "inserted"/"injected" into its scope (3.4/3, 9/2).

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 14, 2006
    #8
    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. maxw_cc
    Replies:
    1
    Views:
    3,148
    Martijn van Steenbergen
    Dec 21, 2003
  2. cppsks
    Replies:
    0
    Views:
    827
    cppsks
    Oct 27, 2004
  3. karthikbalaguru
    Replies:
    9
    Views:
    1,041
  4. Daniel Pitts
    Replies:
    27
    Views:
    1,908
    Mike Schilling
    Feb 27, 2008
  5. Mukesh
    Replies:
    4
    Views:
    626
    Paul N
    Mar 26, 2010
Loading...

Share This Page