nested class inheriting from outer class

Discussion in 'C++' started by Richard Lee, Mar 5, 2008.

  1. Richard Lee

    Richard Lee Guest

    For some reason, this does not compile.

    class A
    {
    public:
    class B : public A
    {
    public:
    B() : A() {}
    };

    protected:
    A() {}
    };

    I can't figure out what is wrong with this construct. It works fine in
    other languages (e.g. Java). It's quite useful to be able to declare a
    class, and then subclass it a bunch of different ways while scoping the
    subclasses to a namespace based on the name of their superclass. I
    can't see any semantic problems, since you can declare nested classes in
    C++, and you can inherit from classes in C++, but you can't do both?

    Maybe it's just a bug in my compiler? I'm using gcc version 4.1.3. Or
    is it a flaw in the C++ language specification?

    Richard
    Richard Lee, Mar 5, 2008
    #1
    1. Advertising

  2. Richard Lee

    yanlinlin Guest

    On Mar 5, 4:50 pm, Richard Lee <> wrote:
    > For some reason, this does not compile.
    >
    > class A
    > {
    > public:
    >      class B : public A
    >      {
    >      public:
    >          B() : A() {}
    >      };
    >
    > protected:
    >      A() {}
    >
    > };
    >
    > I can't figure out what is wrong with this construct.   It works fine in
    > other languages (e.g. Java).  It's quite useful to be able to declare a
    > class, and then subclass it a bunch of different ways while scoping the
    > subclasses to a namespace based on the name of their superclass.  I
    > can't see any semantic problems, since you can declare nested classes in
    > C++, and you can inherit from classes in C++, but you can't do both?
    >
    > Maybe it's just a bug in my compiler?  I'm using gcc version 4.1.3.  Or
    > is it a flaw in the C++ language specification?
    >
    > Richard


    At the position of class B (within class A), the declaration of class
    A has not been finished. Since the compiler can not deside the size of
    class A, you can not derive from it.
    yanlinlin, Mar 5, 2008
    #2
    1. Advertising

  3. Richard Lee

    James Kanze Guest

    On Mar 5, 9:50 am, Richard Lee <> wrote:
    > For some reason, this does not compile.


    > class A
    > {
    > public:
    > class B : public A
    > {
    > public:
    > B() : A() {}
    > };


    > protected:
    > A() {}
    > };


    > I can't figure out what is wrong with this construct.


    It's illegal.

    > It works fine in other languages (e.g. Java).


    Java has to make it work, since it requires all of the
    implementation of A to be encapsulated in A.

    > It's quite useful to be able to declare a class, and then
    > subclass it a bunch of different ways while scoping the
    > subclasses to a namespace based on the name of their
    > superclass.


    Why do you want to scope them to the namespace of the
    superclass? If they're just implementation details, depending
    on your file organization, it might be appropriate to just
    define them in the anonymous namespace of the implementation
    file. Otherwise, there's nothing forbidding you from creating a
    namespace A_private, or whatever, for them. Finally, you can do
    something like:

    class A
    {
    public:
    class B ;
    // ...
    } ;

    class A::B
    {
    public:
    B() ;
    } ;

    > I can't see any semantic problems, since you can declare
    > nested classes in C++, and you can inherit from classes in
    > C++, but you can't do both?


    When you inherit, the class you're inheriting from must be
    complete.

    > Maybe it's just a bug in my compiler? I'm using gcc version
    > 4.1.3. Or is it a flaw in the C++ language specification?


    Neither. It works as designed.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Mar 5, 2008
    #3
  4. Richard Lee

    Guest

    On 5 Mrz., 09:50, Richard Lee <> wrote:
    > For some reason, this does not compile.
    >
    > class A
    > {
    > public:
    > class B : public A
    > {
    > public:
    > B() : A() {}
    > };
    >
    > protected:
    > A() {}
    >
    > };


    It does not compile for good reason. Let's assume the construct were
    allowed. B inherits from A which means everything defined in A is also
    available inside B. This includes B... so B will offer a class B::B
    that is also derived from A. By recursion you'll get B::B::B,
    B::B::B::B, .... ad infinitum.
    The compiler would have to generate an infinite number of types.

    I do not know enough about Java, but I assume it only works if
    embedded classes do not become an integral part of the surrounding
    class.

    best,

    Michael
    , Mar 5, 2008
    #4
  5. Richard Lee

    James Kanze Guest

    On Mar 5, 6:27 pm, wrote:
    > On 5 Mrz., 09:50, Richard Lee <> wrote:


    > > For some reason, this does not compile.


    > > class A
    > > {
    > > public:
    > > class B : public A
    > > {
    > > public:
    > > B() : A() {}
    > > };


    > > protected:
    > > A() {}
    > > };


    > It does not compile for good reason. Let's assume the
    > construct were allowed. B inherits from A which means
    > everything defined in A is also available inside B. This
    > includes B... so B will offer a class B::B that is also
    > derived from A. By recursion you'll get B::B::B, B::B::B::B,
    > .... ad infinitum.
    > The compiler would have to generate an infinite number of types.


    Not really. All that it would mean is that the type A::B is
    present in A::B. Which it is anyway because of class name
    injection.

    Obviously, in this case, A could not have a data member of type
    B.

    > I do not know enough about Java, but I assume it only works if
    > embedded classes do not become an integral part of the
    > surrounding class.


    In Java, variables (data members of classes) can never be
    objects. A variable in Java corresponds to a pointer in C++.
    (There are exceptions for certain fundamental types, like int,
    but they don't concern us here.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Mar 6, 2008
    #5
    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. Replies:
    1
    Views:
    15,339
    cbDevelopment
    Nov 13, 2005
  2. Heiko Henkelmann
    Replies:
    2
    Views:
    489
    Heiko Henkelmann
    Apr 27, 2004
  3. Replies:
    0
    Views:
    394
  4. mrstephengross
    Replies:
    4
    Views:
    463
    Diez B. Roggisch
    Feb 27, 2008
  5. DBak
    Replies:
    11
    Views:
    1,002
Loading...

Share This Page