Topic: [LONGISH] Forward Declaring Nested Classes


Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 6 Nov 2003 00:44:57 +0000 (UTC)
Raw View
alan_mckenney1@yahoo.com (Alan McKenney) wrote
>>     (b) Is there a problem with syntax of the form
>>         "class A::B;" to express this?

> jdennett@acm.org (James Dennett) wrote
>I don't think so.  It's just that it's not something
>that the language should allow.

You want to use
    class A::B;
to forward-declare a class named B that is a (presumably public)
member of B.

Or, would that mean a class named B that is in namespace A?
Why or why not?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: richard@ex-parrot.com (Richard Smith)
Date: Wed, 22 Oct 2003 01:48:50 +0000 (UTC)
Raw View
James Dennett wrote:

> Alan McKenney wrote:
> >     I am told that forward-declaring a nested class
> >     is not allowed in C++.  I would like to ask:
> >
> >     (a) Is there a technical reason why this is not
> >         allowed?
>
> You could violate access protection, if that counts as
> a technical reason.  You could also lie about things
> being members of a class.

This could be resolved by requiring the access specifier to
be included within the declaration, for example,

  class A::public B;

If the compiler also included the access specifier in the
mangled name (as I believe some compilers do), this would
fail to link if B was really a private member of A.
(Admitely uses of the name that didn't require referencing
an external symbol would still compile, but I expect that
real world examples of this would be relatively rare.)

Having said that, I don't believe that this is a
particularly worthy extension to the language.  In my
experience public member classes are rarely useful.
Iterator classes are the primary occasion when I've found
myself using them, and I don't often want to forward declare
these.

--
Richard Smith

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: alan_mckenney1@yahoo.com (Alan McKenney)
Date: Sat, 4 Oct 2003 18:36:08 +0000 (UTC)
Raw View
ABSTRACT:

    I am told that forward-declaring a nested class
    is not allowed in C++.  I would like to ask:

    (a) Is there a technical reason why this is not
        allowed?
    (b) Is there a problem with syntax of the form
        "class A::B;" to express this?

INTRO:

I asked in comp.lang.c++.moderated about how I could
forward declare a class that is defined inside another
class, and was told it was not possible.

In case the issue is not clear, imagine header file
A.h containing:

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

And another (header) file which doesn't use A or A::B
except for pointers to A::B, for example,

    class X {
    ...[no mention of A or A::B] ...

        A::B *f( . . . );
        A::B *b_pointer;
    };


I would like to just write "class A::B;", or something
equivalent, and not have to include A.h.

I was told this was (a) impossible and (b) a Wrong
Thing (tm).

QUTESTION:

    (a) Is there a technical reason why this is not
        allowed, or something more than "we don't
think
        it's good stype"?
    (b) Is there a problem with syntax of the form
        "class A::B;" to express this.


OBLIGATORY REAL-WORLD APPLICATION:

    My software uses a lot of configuration files,
    containing tables of data in the form:

        #  comments
        #  cvs stuff
        key1  key2  value1  value2  value3 ...
        key1  key2  value1  value2  value3 ...

    The number of key fields, the types and meanings
    of the values vary from file to file.

    In order to be cool and hip and object-oriented
    :-) , I create a class for each type of
    config. file, which has functions to read the file
    in, etc., and handles lookup of an entry.

    I end up with classes of the form:

    class AbcTable {
        class Key {
            Key( type1 k1, type2 k2 );
            ....
            };
      public:
        struct Entry {
            ....
            };

       const Entry *lookUp( type1 k1, type2 k2 )
const;
        };


     (I used to use accessors instead of returning
     const Entry *, but they always just returned
     entry_pointer->member, anyway.  "Say what you
     mean," I figure.)


     Now, if function "f" looks up an entry in the
     table, and then wants to call function "g" with
     the entry pointer as an argument, the header file
     with the declaration of "g" has to #include A.h .

     Since I believe that headers #include'ing headers
     should be done as little as possible, I would
     like to just forward declare AbcTable::Entry in
     the header, and only include A.h in the files
     that define f() and g().


     I could declare Entry in global scope, but I
think
     AbcTable::Entry is clearer than AbcTableEntry.

Alan McKenney
alan_mckenney1@yahoo.com



__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jdennett@acm.org (James Dennett)
Date: Sun, 5 Oct 2003 18:54:53 +0000 (UTC)
Raw View
Alan McKenney wrote:
> ABSTRACT:
>
>     I am told that forward-declaring a nested class
>     is not allowed in C++.  I would like to ask:
>
>     (a) Is there a technical reason why this is not
>         allowed?

You could violate access protection, if that counts as
a technical reason.  You could also lie about things
being members of a class.

I don't believe there would be any implementation difficulty
in allowing this; it's just a bad idea.  C++ is quite
consistent in that classes determine their own members.

If you don't need access protection, you don't really
need to use nested types.  Namespaces work quite well
if you want an extensible name space without access
protection.

>     (b) Is there a problem with syntax of the form
>         "class A::B;" to express this?

I don't think so.  It's just that it's not something
that the language should allow.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: alan_mckenney1@yahoo.com (Alan McKenney)
Date: Tue, 7 Oct 2003 00:45:57 +0000 (UTC)
Raw View
jdennett@acm.org (James Dennett) wrote in message news:<N1Pfb.7974$La.7165@fed1read02>...
> Alan McKenney wrote:
> > ABSTRACT:
> >
> >     I am told that forward-declaring a nested class
> >     is not allowed in C++.  I would like to ask:
> >
> >     (a) Is there a technical reason why this is not
> >         allowed?
>
> You could violate access protection, if that counts as
> a technical reason.  You could also lie about things
> being members of a class.

Well, allowing "class A::B;" would allow one to declare
pointer [variables] of a type that would turn out to
be inaccessible.  But without the full definition of "A",
you couldn't do anything with values of type A::B*
except pass them around.  To create the values, manipulate
them, etc., you would need the full definition.
This doesn't sound so dangerous to me, but perhaps wiser
folks see deeper pitfalls than I.

I don't know what you mean about "lie about things being
members of a class."  If you're talking about the outer
class, (based on my experience with the Sun
solaris compiler) a nested class has no more access
to the outer class's members, types, etc., than an unrelated
class would.  (In both cases, I need "friend" declarations
to access the outer class's non-public types, members, etc.)

If you're talking about access to the inner class, it's no
different for the inner class than a class defined in global
scope, AFAIK.

Yes, this feature could be misused, but so can the existing
features, and in the same ways.  I adhere to Stroustrup's
view in D&E, that the goal is to prevent inadvertent violations
of type, access, etc., not to make it impossible for people
to deliberately get around the rules, or to prevent
politically incorrect styles of programming.


<snip>

> If you don't need access protection, you don't really
> need to use nested types.  Namespaces work quite well
> if you want an extensible name space without access
> protection.

Well, if I could have a namespace that defines the same scope
as a particular class, that would be fine.  The outer
scope *is* defining a type, so a bare namespace won't work.
And since the whole point of nesting the inner class is
to show the association of this class with the outer class
(see the "real-world application" in my original post),
there would be no point at all in putting it in a separate
namespace; global would make just as much sense, and be
easier to use.


Two points about where I'm coming from here:

1.  This restriction is not a big problem for me;
    it just forces me to do things in an (IMHO)
    less-than-elegant way.


2.  On the other hand, I haven't found the replies
    all that convincing.  I'm not saying they are
    wrong, but what is written is pretty sketchy:
    I can't tell if it's because the objections to
    "class A::B;" are obvious to everyone but me,
    or because no one has thought too much about
    it.

I guess what I wish I could see are specific explanations
of how allowing this would create more opportunities
for programmers doing normal (=non-pathological)
programming to shoot themselves in the foot.




Alan McKenney
alan_mckenney1@yahoo.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]