[comp.lang.c++] const vs. static in class declaration

lma@dayton.Stanford.EDU (Larry Augustin) (03/27/91)

I have a number of integer constants that are part of a class.  What
is the correct way to go about doing this?  I have been using:


   class foo {
    private:
	...
    protected:
	...
    public:
      const int ID      = 258;
      const int NUMBER  = 259;
      const int IPORT   = 260;
	...
    };

But I've been told that this only works in g++, and isn't standard.  I
would like to avoid doing anything in my my application that isn't
portable.

Just so you understand the context, there may also be a class:

   class bar {
    private:
	...
    protected:
	...
    public:
      const int ID      = 230;
      const int NUMBER  = 231;
      const int IPORT   = 232;
	...
    };

So I don't simply want to use a #define or a global constant.

Thanks,

Larry M. Augustin			ERL 414
lma@sierra.stanford.edu			Computer Systems Lab
lma@dayton.stanford.edu			Stanford University
(415) 723-9285				Stanford, CA 94305
-- 
Larry M. Augustin			   _         _      _     ____
					  | |	    | \    / |	 / __ \
ARPA: lma@sierra.stanford.edu		  | |	    |  \__/  |	| (__) |
BITNET: lma%sierra.stanford.edu@stanford  | |	    | |\  /| |	|  __  |
UUCP:...!ucbvax!sierra.stanford.edu!lma   | |____   | | \/ | |	| |  | |
AT&T: (415) 324-4929			  |______|  |_|    |_|	|_|  |_|

jenings@hpfcbig.SDE.HP.COM (Byron Jenings) (03/29/91)

 Larry Augustin <lma@dayton.Stanford.EDU> writes:
|I have a number of integer constants that are part of a class.  What
|is the correct way to go about doing this?  I have been using:

|   class foo {
|    private:
|	...
|    protected:
|	...
|    public:
|      const int ID      = 258;
|      const int NUMBER  = 259;
|      const int IPORT   = 260;
|	...
|    };

|But I've been told that this only works in g++, and isn't standard.  I
|would like to avoid doing anything in my my application that isn't
|portable.

I believe that this is the proper way to do this:


In the header file:

   class foo {
    private:
       ...
    protected:
       ...
    public:
      static const int ID;	// note that 'static' doesn't refer to linking
      static const int NUMBER;
      static const int IPORT;
       ...
    };

Then, in the corresponding C++ source file that implements the members
of class foo:

const int foo::ID      = 258;
const int foo::NUMBER  = 259;
const int foo::IPORT   = 260;

roger@grenada.island.COM (Roger Corman) (03/30/91)

In article <286@dayton.stanford.edu> lma@dayton.Stanford.EDU (Larry Augustin) writes:
>I have a number of integer constants that are part of a class.  What
>is the correct way to go about doing this?  I have been using:
>
>
>   class foo {
>    private:
>	...
>    protected:
>	...
>    public:
>      const int ID      = 258;
>      const int NUMBER  = 259;
>      const int IPORT   = 260;
>	...
>    };
>
>But I've been told that this only works in g++, and isn't standard.  I
>would like to avoid doing anything in my my application that isn't
>portable.
>
Your way does not work with CFront.  Two ways to do this (using 'static
const' and enum) are shown in this example.  Only the enum lets you actually
include the initializer value in the class definition.  The static const
requires that the initializer be outside the class definition (usually the
not in an #include file).
------------------------------------

#include <iostream.h>

class foo
{
public:
	foo(){}
	static const int ID;
	enum {IPORT=100};
};
	
const int foo::ID = 200;

main()
{
	foo f;
	
	cout << f.ID << "\n";
	cout << f.IPORT << "\n";
	cout << foo::IPORT << "\n";
	cout << foo::ID << "\n";
}
	

------------------------------
Roger Corman
Island Graphics
149 Stony Circle, Suite 200
Santa Rosa, CA 95401
(707)523-4465
{uunet,sun,ucbcad!island!roger} 

class Disclaimer
{
private:
    ObscureStuff employerOpinions;
public:
    UsefulAdvice myOpinions[MAXINT];
};

chris@island.COM (Chris King) (04/03/91)

roger@grenada.island.COM (Roger Corman) writes:
> Roger expains how to declare a const static class member.

Initialization of const static class members are one thing that I really
think have been poorly thought out in c++. I didn't realize that g++
allowed them to be initialized in the class decleration. This seems
like a defininate improvment over cfront. I hope the ansi commitee
will consider adding this g++ feature to the standard.

In addition, one thing that I wish I could do is the following:

class array_of_jive {
    static const int num_elements = 10;
    struct jive a[num_elements];

    void tweak_all()
    {
	for ( int i = 0 ; i < num_elements; ++i )
	    a[i].tweak();
    }
};
       
but unfortunatly the compiler won't let me do this, so, rather than
use a define (I hate defines), I usually do the following:

class array_of_jive {
    struct jive a[10];

    inline int num_elements() { return(sizeof(a)/sizeof(struct jive)); }

   void tweak_all()
   {
       for ( int i = 0 ; i < num_elements(); ++i )
           a[i].tweak();
    }
};

Has anybody found a easier way of doing this.

					Chris King
					Island Graphics Corp.
					San Rafael Ca.
					{sun,ucbcad,uunet}!island!chris
						

hitz@sim5.csi.uottawa.ca (Martin Hitz) (04/04/91)

In article <3864@island.COM> chris@island.COM (Chris King) writes:
>Initialization of const static class members are one thing that I really
>think have been poorly thought out in c++. 
> [...]
>rather than
>use a define (I hate defines), I usually do the following:
>
>class array_of_jive {
>    struct jive a[10];
>
>    inline int num_elements() { return(sizeof(a)/sizeof(struct jive)); }
>
>   void tweak_all()
>   {
>       for ( int i = 0 ; i < num_elements(); ++i )
>           a[i].tweak();
>    }
>};
>
>Has anybody found a easier way of doing this.

No. I agree that this is a major uglyness in C++. However, I *do* use
a define in such a case to avoid declaration of N inline functions for
N arrays:

#define DIM(array) (sizeof(array)/sizeof(*array))

class array_of_jive {
   struct jive a[10];

   void tweak_all()
   {
       for ( int i = 0 ; i < DIM(a); ++i )
           a[i].tweak();
    }
};

Martin Hitz (hitz@csi.UOttawa.CA)

steve@taumet.com (Stephen Clamage) (04/05/91)

hitz@sim5.csi.uottawa.ca (Martin Hitz) writes:

>However, I *do* use a define in such a case to avoid declaration of
> N inline functions for N arrays:

>#define DIM(array) (sizeof(array)/sizeof(*array))

ARRRRGGGGHHH!  Use inline member or non-member functions to do this.
They will be evaluated at compile time by any decent compiler, and
it avoids the nasty problems of mismatched types and unscoped names
endemic to macros.  IMHO this far outweighs the few minutes spent
declaring the inline functions.  (There is no other penalty, since
the functions can all have the same name, "DIM" if you like.)
===========
class illumination {
    BRIGHTEN(int);
    DIM(int);		// illegal due to macro
};
===========
char *ray;		// legal but misleading -- proper set of inline
int sz = DIM(ray);	// functions would give error at compile time
===========
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com