Topic: constants in classes


Author: comeau@panix.com (Greg Comeau)
Date: 1997/01/03
Raw View
In article <01bbf693$ef079ea0$904697c2@fvl.iaehv.nl> "F. van Leeuwen" <fvl@iaehv.nl> writes:
>I have two proposals for a new C++ standard. But if there
>is a good reason not to include them, I am prepared for a
>discussion.

At first glance, this message may seem redundant given the other
reponses, however, I think the responses to this message left out a
number of important issues w.r.t this.

>1. In C++, I can declare a constant that has a class scope:
>
>class foe {
>   ...
>   const int SOME_CONST;
>   ...
>};
>
>which is a very nice feature. But WHY CAN'T I give it a
>value in the class definition?

You _cannot_ because of the combination of a number of things:
ODR (one definition rule), complexity to implementors, "competition"
with member initializer lists, possibility for error, lack of an
object, order of initialization, etc.

This alone is indicative for you to be sure that indeed you
definitely want to do something such as this.  If after analysis,
you still do, you have a number of choices.  You mention this,
but it is NOT a choice:

>Now, I have to specify it's value outside the class definition:
>
>foe::SOME_CONST = 15;

Why?  Because SOME_CONST is not static.  It it were, it is not
clear if you mean this to be done via assignment, but if so,
this would be an error, because it is const.  This would leave
this possibility:

class foe {
    static const int SOME_CONST;
};

const int SOME_CONST = 15; // AA

>why can't I just declare:
>
>class foe {
>   ...
>   const int SOME_CONST = 15;
>   ...
>};

See above for why.  However, you can now do this:

class foe {
   static const int SOME_CONST = 15; // BB
};
const int SOME_CONST; // still needed, but w/o init'r // CC

However, you need to consider how much it really gains you.

Anyway, note a static const integral is involved.  That
(actually static const enumerations too) is the limit to this
extension (IOW, it is not allowed if it were a float.  Also, the
init'r must be a constant expression).

>Note that it does work with ints, but I have to rewrite it as:
>
>class foe {
>   ...
>   enum { SOME_CONST = 15 };
>   ...
>};
>

This remains a possibility.

As well, please do not get caught up in being able to do this and
underestimate what the old tried and true as per version AA above
can give you (remembering that statics can be private).

- Greg
--
       Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
               Producers of Comeau C++ 4.0 front-end pre-release
****WEB: http://www.comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
 Here:comeau@comeaucomputing.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: RonD <rond@cs.huji.ac.il>
Date: 1997/01/06
Raw View
F. van Leeuwen wrote:
>
> I have two proposals for a new C++ standard. But if there
> is a good reason not to include them, I am prepared for a
> discussion.
>
> 1. In C++, I can declare a constant that has a class scope:
>
> class foe {
>    ...
>    const int SOME_CONST;
>    ...
> };
>
> which is a very nice feature. But WHY CAN'T I give it a
> value in the class definition? Now, I have to specify it's
> value outside the class definition:
>
> foe::SOME_CONST = 15;
>
> why can't I just declare:
>
> class foe {
>    ...
>    const int SOME_CONST = 15;
>    ...
> };

 Wait a minute here:

  The construct:

   class X
   {   public:
          const int C;
   }

   treats C as constant of an instance of X, not of every X who will
   ever be created. To make a constant for the whole class use

   class X
   {   public:
          static const int C;
   }

   or for ints, use the enum {} version.

   Ron.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "F. van Leeuwen" <fvl@iaehv.nl>
Date: 1996/12/30
Raw View
I have two proposals for a new C++ standard. But if there
is a good reason not to include them, I am prepared for a
discussion.

1. In C++, I can declare a constant that has a class scope:

class foe {
   ...
   const int SOME_CONST;
   ...
};

which is a very nice feature. But WHY CAN'T I give it a
value in the class definition? Now, I have to specify it's
value outside the class definition:

foe::SOME_CONST = 15;

why can't I just declare:

class foe {
   ...
   const int SOME_CONST = 15;
   ...
};

Note that it does work with ints, but I have to rewrite it as:

class foe {
   ...
   enum { SOME_CONST = 15 };
   ...
};


My second proposal is as follows:

If a have a class, let's say CSon, derived from class CGrandDad, and
I want to redefine class CSon to be derived from CDad, which is derived
from CGrandDad, I have to change all member functions that call the
bass class, like CGrandDad::foe(); to CDad::foe();
In Java, this is more elegant; they have a keyword for it. I believe
it is called 'super'. So I could write super::foe(); to call the bass
class function. Because if I forget to change one of the CGrandDad::
calls, I am calling the base class of the bass class, bypassing the
single bass class. This could cause erratic code.

Frank van Leeuwen
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: stephen.clamage@Eng (Steve Clamage)
Date: 1996/12/31
Raw View
In article 904697c2@fvl.iaehv.nl, "F. van Leeuwen" <fvl@iaehv.nl> writes:
>I have two proposals for a new C++ standard. But if there
>is a good reason not to include them, I am prepared for a
>discussion.
>
>1. In C++, I can declare a constant that has a class scope:
>
>class foe {
>   ...
>   const int SOME_CONST;
>   ...
>};
>
>which is a very nice feature. But WHY CAN'T I give it a
>value in the class definition?

You can. See any recent version of the draft standard, such as
the publicly-available April 1995 version. (That version is
out of date, but correctly describes this particular feature.)
Not many compilers implement the feature yet.


>My second proposal is as follows:
>
>If a have a class, let's say CSon, derived from class CGrandDad, and
>I want to redefine class CSon to be derived from CDad, which is derived
>from CGrandDad, I have to change all member functions that call the
>bass class, like CGrandDad::foe(); to CDad::foe();
>In Java, this is more elegant; they have a keyword for it. I believe
>it is called 'super'. So I could write super::foe(); to call the bass
>class function. Because if I forget to change one of the CGrandDad::
>calls, I am calling the base class of the bass class, bypassing the
>single bass class. This could cause erratic code.

That proposal has been discussed many times here and in other newsgroups.
It was also discussed by the C++ Committee and rejected. See "The
Design and Evolution of C++" by Bjarne Stroustrup for an evaluation.
---
Steve Clamage, stephen.clamage@eng.sun.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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: pwolf@qualcomm.com (Paul Wolf (Mac))
Date: 1997/01/02
Raw View
You can declare an enum which is a set of const integers inside a class
definition.

In article <01bbf693$ef079ea0$904697c2@fvl.iaehv.nl>, "F. van Leeuwen"
<fvl@iaehv.nl> wrote:

> I have two proposals for a new C++ standard. But if there
> is a good reason not to include them, I am prepared for a
> discussion.
>
> 1. In C++, I can declare a constant that has a class scope:
>
> class foe {
>    ...
>    const int SOME_CONST;
>    ...
> };
>
> which is a very nice feature. But WHY CAN'T I give it a
> value in the class definition? Now, I have to specify it's
> value outside the class definition:
>
> foe::SOME_CONST = 15;
>
> why can't I just declare:
>
> class foe {
>    ...
>    const int SOME_CONST = 15;
>    ...
> };
>
> Note that it does work with ints, but I have to rewrite it as:
>
> class foe {
>    ...
>    enum { SOME_CONST = 15 };
>    ...
> };
>
>
> My second proposal is as follows:
>
> If a have a class, let's say CSon, derived from class CGrandDad, and
> I want to redefine class CSon to be derived from CDad, which is derived
> from CGrandDad, I have to change all member functions that call the
> bass class, like CGrandDad::foe(); to CDad::foe();
> In Java, this is more elegant; they have a keyword for it. I believe
> it is called 'super'. So I could write super::foe(); to call the bass
> class function. Because if I forget to change one of the CGrandDad::
> calls, I am calling the base class of the bass class, bypassing the
> single bass class. This could cause erratic code.
>
> Frank van Leeuwen
> ---
> [ comp.std.c++ is moderated.  To submit articles: Try just posting with your
>                 newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
>   comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
>   Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
>   Comments? mailto:std-c++-request@ncar.ucar.edu
> ]
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/01/02
Raw View
"F. van Leeuwen" <fvl@iaehv.nl> writes:

> I have two proposals for a new C++ standard. But if there
> is a good reason not to include them, I am prepared for a
> discussion.
>
> 1. In C++, I can declare a constant that has a class scope:
>
> class foe {
>    ...
>    const int SOME_CONST;
>    ...
> };
>
> which is a very nice feature. But WHY CAN'T I give it a
> value in the class definition?

According to the current draft, you can, at least if the constant has an
integral type, and the initializer is a constant expression.  And the
resulting const can be used in a constant expression, e.g.: to declare
an array.

> Now, I have to specify it's
> value outside the class definition:
>
> foe::SOME_CONST = 15;
>
> why can't I just declare:
>
> class foe {
>    ...
>    const int SOME_CONST = 15;
>    ...
> };
>
> Note that it does work with ints, but I have to rewrite it as:
>
> class foe {
>    ...
>    enum { SOME_CONST = 15 };
>    ...
> };

This used to be the case.  In fact, your proposal has already been
proposed and accepted.

> My second proposal is as follows:
>
> If a have a class, let's say CSon, derived from class CGrandDad, and
> I want to redefine class CSon to be derived from CDad, which is derived
> from CGrandDad, I have to change all member functions that call the
> bass class, like CGrandDad::foe(); to CDad::foe();
> In Java, this is more elegant; they have a keyword for it. I believe
> it is called 'super'. So I could write super::foe(); to call the bass
> class function. Because if I forget to change one of the CGrandDad::
> calls, I am calling the base class of the bass class, bypassing the
> single bass class. This could cause erratic code.

The normal way of doing this in C++ is with a typedef, e.g.:

 class CSon : public CGrandDad { typedef CGrandDad parent ; ... } ;

and calling parent::foe(), etc.  To change the inheritance, just change
the typedef, e.g.:

 class CSon : public CDad { typedef CDad parent ; ... } ;

This doesn't work as well as one would like in the presence of multiple
inheritance, but is adequate most of the time.

--
James Kanze         +33 (0)3 88 14 49 00         email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]