Topic: A plea for reopening class declarations


Author: tob@world.std.com (Tom O Breton)
Date: Sun, 12 Feb 1995 04:40:59 GMT
Raw View
spitzak@news.cinenet.net (Bill Spitzak) writes:
> I have suggested this before and never gotten any response.  Perhaps I
> don't know what I am talking about, I would appreciate it if someone
> would at least correct me.

That's odd. I distinctly remember responding. I'll repeat the gist of it
here:

If there are more than two "parts", there's a danger of including them
out of order, and/or of omitting some.

        Tom

--
tob@world.std.com
TomBreton@delphi.com: Author of The Burning Tower





Author: jvsb@sebb.bel.alcatel.be (Johan Vanslembrouck)
Date: 10 Feb 1995 11:56:43 GMT
Raw View
 ***************************************
 A plea for reopening class declarations
 ***************************************

In this poster I want to hold a plea for reopening class declarations,
or in other words, to be able to declare a class in several parts.
As an example, I want to be able to write something like:

 class MyClass
 {
  // first N1 members
 };

 class MyClass
 {
  // next N2 members
 };

 // etc ...

I will try to show that such a feature is very useful in combination
with templates.


The following is taken from a real application.
For this application I'm currently in the process of replacing
cpp macros by class templates.
Unfortunately, I'm unable to replace some of the larger macros.

Consider the following application class:

 class Address : public TransObject
 {
  char street[40];
  short number;
  long zipcode;
  char city[40];
    public:
  // etc ...
 };

In order to transport Address objects over the network,
I define a companion class enc_Address in the following
way (using a cpp macro called STRUCT_CLASS_BEGIN):

 STRUCT_CLASS_BEGIN(Address)
 };

(The .c file contains a table description of the 4 data members
 of class Address, but for our discussion this is of no importance.)

STRUCT_CLASS_BEGIN declares the complete companion class
apart from the closing "};"
It is very well possible to replace the combination of
STRUCT_CLASS_BEGIN + }; by a class template.

The reason why I chose not to "close" the class declaration in the
STRUCT_CLASS_BEGIN macro is because I can also write something like:

 STRUCT_CLASS_BEGIN(Address)
  DEF_FIELD(char, street,  0)
  DEF_FIELD(long, zipcode, 2)
  DEF_FIELD(char, city,  3)
  DEF_FIELD(char, town,  3)
 };

The DEF_FIELD macro defines a set of member functions for
selected data members of class Address. This allows me to
access individual Address data members in the message.

Currently I don't see a way to replace the rather large
STRUCT_CLASS_BEGIN and DEF_FIELD macros by class or function
templates.

However, if it was allowed to reopen a class definition, then I
could rearrange the macros above and write something like:

 STRUCT_CLASS_BEGIN(Address)
 };
 DEF_FIELD(Address, char, street,  0)
 DEF_FIELD(Address, long, zipcode, 2)
 DEF_FIELD(Address, char, city,  3)
 DEF_FIELD(Address, char, town,  3)

DEF_FIELD now reopens the enc_Address class definition and
adds a number of member functions. From here on, it would be
only a small step to replace the macros by class templates.

There is yet another extension I need. The third argument
in the (new) DEF_FIELD macro is used to build member names.
This is currently impossible with C++ templates because
of the typed-ness of the template arguments (a good thing).
But wouldn't it be a good thing to have a type "identifier"
which could be used to abstract e.g. member names
in the formal template argument list?

A template alternative for the cpp macros STRINGIZE
and name2, name3, ... would also be rather useful.

Concluding, this is what I would like to have (in order of importance):

 1) the possibility to reopen class declarations
 2) a way to abstract identifiers (like member names)
    in the template argument list
 3) a template alternative for STRINGIZE, name2, name3, ...

Having this available I would be able to replace
almost all of my rather large cpp macros by templates.

Does anyone has comments on these proposals?

If there are other alternatives to solve my problem and
which do not require an extension of the language definition,
I would be happy to learn about them.

(Note: the proposal to have a template for 0 fields, one for 1 field,
one for 2 fields, ..., one for n fields, I reject at beforehand. Sorry.)

Thanks in advance,

Johan


-----------------------------------------------------------------------
Johan Vanslembrouck - SE99            Tel    : +32 3 2407739
Alcatel Bell Telephone                Telex  : 72128 Bella B
Francis Wellesplein  1                Fax    : +32 3 2409932
B-2018 Antwerp                        e-mail : jvsb@sebb.bel.alcatel.be
Belgium
-----------------------------------------------------------------------




Author: tob@world.std.com (Tom O Breton)
Date: Fri, 10 Feb 1995 23:23:13 GMT
Raw View

jvsb@sebb.bel.alcatel.be (Johan Vanslembrouck) writes:
> If there are other alternatives to solve my problem and
> which do not require an extension of the language definition,
> I would be happy to learn about them.

I can see 2 other alternatives:

        #define STRUCT_CLASS_BEGIN( Address ) /* blah, blah */

        #define STRUCT_CLASS_END };

        STRUCT_CLASS_BEGIN(Address)
        /* Other stuff */
        STRUCT_CLASS_END


...or...

        #define STRUCT_CLASS_( Address, otherstuff ) \
        /* blah, blah */ \
        otherstuff;\
        };

STRUCT_CLASS_( Address,
        DEF_FIELD(char, street,         0);
        DEF_FIELD(long, zipcode,        2);
        DEF_FIELD(char, city,           3);
        DEF_FIELD(char, town,           3)
        );


        Tom

--
tob@world.std.com
TomBreton@delphi.com: Author of The Burning Tower





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Sat, 11 Feb 1995 04:23:25 GMT
Raw View
jvsb@sebb.bel.alcatel.be (Johan Vanslembrouck) writes:

>In this poster I want to hold a plea for reopening class declarations,
>or in other words, to be able to declare a class in several parts.

You've got Buckley's.

>As an example, I want to be able to write something like:
>
> class MyClass
> {
>  // first N1 members
> };

What happens if I write

 MyClass x;

here, before the class definition is complete?
How many bytes does the compiler allocate for `x'?

> class MyClass
> {
>  // next N2 members
> };

This would completely break the encapsulation.

 #include "library.h" // defines class `LibraryClass'

 class LibraryClass { // extend the definition of the class
  void my_func() {
   // now I can access the private members of the class
  }
 };

> STRUCT_CLASS_BEGIN(Address)
>  DEF_FIELD(char, street,  0)
>  DEF_FIELD(long, zipcode, 2)
>  DEF_FIELD(char, city,  3)
>  DEF_FIELD(char, town,  3)
> };
>
>The DEF_FIELD macro defines a set of member functions for
>selected data members of class Address. This allows me to
>access individual Address data members in the message.
>
>Currently I don't see a way to replace the rather large
>STRUCT_CLASS_BEGIN and DEF_FIELD macros by class or function
>templates.

How about

 struct enc_Address {
  Field<char, 0> street;
  Field<long, 2> zipcode;
  Field<char, 3> city;
  Field<char, 3> town;
 };

?

--
Fergus Henderson - fjh@munta.cs.mu.oz.au
all [L] (programming_language(L), L \= "Mercury") => better("Mercury", L) ;-)




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sat, 11 Feb 1995 11:43:43 GMT
Raw View
In article <1995Feb10.125514@sebb.bel.alcatel.be> jvsb@sebb.bel.alcatel.be (Johan Vanslembrouck) writes:
>
> A plea for reopening class declarations
>
>In this poster I want to hold a plea for reopening class declarations,
>or in other words, to be able to declare a class in several parts.

 ONLY if there is a part marked FINAL, after which
reopening is an error, and such part must be lexically included
in the translation unit declaring the first part, and the FINAL
part must be given before a "use" of the class (eg an instantiation)
that requires knowing the length of the object. (This is not
necessary in theory but is required for current brain dead linkage
technology)

 The first requirement (a FINAL part) is mandatory
to allow encapsulation to be enforced. Without it,
object oriented programming is reduced to a fraud.


--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: spitzak@news.cinenet.net (Bill Spitzak)
Date: 11 Feb 1995 08:49:26 -0800
Raw View
jvsb@sebb.bel.alcatel.be (Johan Vanslembrouck) writes:


> ***************************************
> A plea for reopening class declarations
> ***************************************

I have suggested this before, with the addition that the "..." token
is required to indicate that there is a previous/next piece:

 class MyClass {
  <first N1 members>
  ... // indicates that there is more
 };

 class MyClass {
  ... // required
  <next N2 members>
  ... // indicates that there is more
 };

 class MyClass {
  ... // required
  <last members>
 };

The '...' is so the pieces can be in seperate source/.H files and
compiliation will fail if a header is not included.

<The syntax "class MyClass {...};" means the same as a leading "..."
followed by a zero-length list of members.  "class MyClass {... ...};"
means the same as a leading and trailing "..." around a zero-length
list.  To get the effect of a zero-length list followed by a "..."
just use the (already existing) "class MyClass;">

If only a partial class declaration has been encountered you can only
declare and use pointers to that class, and you can dereference any of
the members you know about.  You cannot subclass from it.

I have suggested this before and never gotten any response.  Perhaps I
don't know what I am talking about, I would appreciate it if someone
would at least correct me.

===

A totally different point but one that solves a lot of the reason for
the original request is to be able to declare private non-virtual
functions and static variables without them being in the header:

 class MyClass {
     private:
  int foo(int); // this line is now optional!
  static int bar; // so is this line!
 };

 int MyClass::foo(int) {...}
 int MyClass::bar = 46;

I think this has been asked for many many times.  Is there anything
wrong with it?  I can't see how it would break any possible C++
implementation.

===

Bill Spitzak
spitzak@d2.com