Solved

class C {static const PROPERTY;....}   //won't work

Posted on 1998-04-30
26
307 Views
Last Modified: 2010-04-10
I am having trouble with a class which holds a constant as a property. I thought I would make the property a static to prevent it being copied for every class object but my compiler won't let me. When I make the const a static I can't define it in the private or public section and when I try to define it at file scope the compiler won't let me. Bjarne says that you can declare the statics as long as you define them later, but how can this be done for a const.  

At the moment I've made the const a global but I'd prefer if it weren't. I suppose I could make the const private but I'd have to rewrite all the other member functions to cope with this. I'd like to know what the best workaround for this problem is if there is one.

0
Comment
Question by:gavinpat
  • 8
  • 8
  • 7
  • +2
26 Comments
 
LVL 1

Expert Comment

by:slinky
Comment Utility
how are you trying to define the static within the class?
(and what compiler is this?)
0
 
LVL 11

Accepted Solution

by:
alexo earned 50 total points
Comment Utility
Using structs to simplify things:

1) Any compiler should accept:

    // in .H file
    struct X
    {
        static const int PROP;
    };

    // in .CPP file
    const int X::PROP = 17;

More...
0
 
LVL 11

Expert Comment

by:alexo
Comment Utility
2) If the "static const" is integral, every compiler should accept:

    // in .H file
    struct X
    {
        static enum { PROP = 17 };
    };


3) NEW compilers that conform to the C++ draft standard will accept:

    // in .H file
    struct X
    {
        static const int PROP = 17;
    };

Unfortunately, most compilers do not support (3) yet, so you're stuck with (1) or (2).

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Am I missing something?  There is no reason to declare a "static int" as "constant".  A "constant int" is sufficient.  It is better than a static int.  A "constant int" will (ussually) be used as a sort-of inline value that is hardcoded into your program code.  A static int (constant or not) will be stored in your program's data.  This is less efficient.

Now if the data we are talking about is not an integral type, like char, int, bool, or enum then "static const int" might make sense.  
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Never mind my comment.  I keep forgeting that you can't declare constants within a class.  You can declare enumerated types and use them as constants, but not constants.  That is very annoying.
0
 

Author Comment

by:gavinpat
Comment Utility
I should have noted that the static const was not an int but a double. Does this complicate things?
0
 
LVL 11

Expert Comment

by:alexo
Comment Utility
That will prevent you from using the "enum" version.  The first option will still work.

0
 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
You cannot define static member variables within a class (only declare them)

You MUST define static members at file scope for a single source file (otherwise it is multiply defined).

NOTE: Non-static member must be initialized (if at all) in a constructor.

So ... you should be able to say (with no problems)

in X.h:
class X {
  static const double myconst;
};

in X.cpp:
const double X::myconst = 1.0;

This should work fine.

Note: A NON-STATIC const member will take up room in EVERY object (probably not what you want).  However, sometimes it CAN be useful, as long as the initial value can be different for each object.

eg.

class X {
  const int which;
  static int next;
public:
  X() : which(next++) {}
};

Here, 'which' is a non-static const member and will take up room in each object.  However, the value of 'which' is different (but const) for each object created.  NOTE: you still need to define 'next' in some .cpp file.

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Roger, Alex,  
Alexo's option number 3 both declares and defines a static constant INSIDE the class/structure declaration.  I know that was not a possibile in the previous "standards".  But is that possible in the new standard.  You seem to dissagree.  It would be really nice if it was possible.
0
 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
It would seem to be a sensible (and long awaited) change to the standard.

However, I don't believe that is yet part of the C++ standard - certainly not part of the standard that is actually implement by any (commercial) compilers

0
 
LVL 11

Expert Comment

by:alexo
Comment Utility
Unless my grey cell count has hit senility level it is a part of the FDIS.
However, please note that I was specifically referring to CONST static members.
0
 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
Aha .. they do seem to be part of the language now .. my apologies.  I hadn't realized that the standard allows for const static members to be inited in a class declaration.  Although I don't see why the standard would insist they have to be const to be initialized that way.

I don't think they are in VC though?  Guess it's not modern enough :-)

0
 
LVL 11

Expert Comment

by:alexo
Comment Utility
OOPS!  Shame on you people, nobody corrected my mistake.

Here goes the correction:

2) If the "static const" is integral, every compiler should accept:

          // in .H file
          struct X
          {
              // Error: static enum { PROP = 17 };
              enum { PROP = 17 }; // Correct, lose the "static".
          };

Moving on...

>> Although I don't see why the standard would insist they have to be const to be initialized that way.
Because if they are const, they can be generated inline and not allocated anywhere.  Ever tried taking the address of a const int variable?

BTW, would anyone of you people have an idea where an economically challenged person can get a copy of the FDIS?  Hypothetically speaking, of course...
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
I don't see how a static data member being inline is any different from a member function being inline.  The code for the function (may) still have to be generated somewhere.  Similarly for templated functions .. the compiler seem able to find a place to place the generated code of an instatiated template.

Can you not take the address of a const int variable?  I thought you could?  And my compiler seems to think so too.

0
 
LVL 11

Expert Comment

by:alexo
Comment Utility
The compiler is not required to allocate it.  It can just use it as if it was a literal.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Yes, you can take the address of a const int.  However--and I'm just guessing here--two different instances of addresses of the constant int might not yeild the same addresses, especially if they are from different translation units.  The also happens with functions.  A member function (inlined or not) that is in a header file might be compiled into the program at several locations.  If you try to get the address from different translation units you might get different addresses.  Same sort of thing with template functions.

So if the inline function/data is not used inline, it might have several copies stored in the program.  This is why you should not try to inline things that you know can't be inlined, like recursive functions or functions you take addresses of.  
0
 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
consider this.

X.h:
  class X {
    void f();
  };
X.cpp:
  void X::f() {
    static int count=0;
    count++;
  }

as opposed to this

Y.h:
  class Y {
    void f() {
      static int count=0;
      count++;
    }
  };

Are you saying that there will be more than one instance of count in Y::f() ?? if so, that means that static vars cannot really be used in in-line functions (and therefore not in templates).  I don't think that is so.

So that means the count var in Y::f() MUST be being allocated and initialized SOMEWHERE .. but the definition does not occur in any particular cpp.

So, if this can work, why not this (if it were allowed for in the standard).

class Z {
  static int count = 0;
  void f() {
    count++;
  }
};

Is count in class Z really that much different from count in Y::f?  Surely the same sort of mechanism could be used to allocate space for the static variable and for initializing it?

0
 
LVL 11

Expert Comment

by:alexo
Comment Utility
First, I was wrong about the address of const.  The compiler is free to eliminate the allocation of a const *only* if it can determine that (a) its value is known at compile time and (b) its address will not be taken.

Second, a function (member or otherwise) will always have one address.  The linker will either eliminate (merge?) duplicate instances or barf on them.

Third, Roger's "class Z" example is valid according to the new rules.

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
I know you guys both have "Effective C++"  Take a look at the bottom of page 108 and page 109.  It discusses how multiple copies of a non-inlined function can be placed in the file.  It does no mention the fact that the address operator applied to these functions will return different addresses.  (It did say that before, but the book was rewritten while sitting on my shelf.)  I believe the same stuff is true for constants and templates.  I beleive that also appears in this book, but I'm not checking now as I took yesterday "off" and got piles of stuff to do.

0
 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
I don't have that book I'm afraid .. maybe that is why my C++ is ineffective :-)

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Wow!  I honestly thought every C++ programmer had them.  Do yourself a favor  Get them.  "Effective c++" and "More Effective C++"  By Scott Meyers.  They are each on about 30 advanced topics and pitfalls of C++.  These are not comprehesive C++ books they just cover these select topics.  Most of it you obviously know by now, but I suspect there will be some things you don't know.  
0
 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
There always is .. don't think any of us knowit all (tho we might like to think we do :-)

I'll see if I can get a hold of a copy.
0
 

Author Comment

by:gavinpat
Comment Utility
One further comment alexo, does C++ builder support your definition: 3)
(definition of static consts within the class declaration), VC5 does not, not even with service pack 3 added.
0
 
LVL 11

Expert Comment

by:alexo
Comment Utility
I think that the number of compilers that support it TODAY can be counted on one thumb :-)  The situation will be different in, say, six months.

No, C++B probably does not support it.

Todd, Roger: wht's your suggested C++ "must have" books?
My list is:
    The C++ programming language, 3rd edition (stroustrup).
    EC++ and MEC++ (Meyers)
    Design patterns (Gamma et al)

0
 
LVL 10

Expert Comment

by:RONSLOW
Comment Utility
alexo .. but is that thumb pointing up or down :-) Do you actually know of one, perhaps G++ (I think Comeau supports it).

All I have is a draft of C++ std and the MS tutorials.  C++ wasn't all that hard to pick up .. and I studied OO techniques while at UNI (they weren't taught then .. structured programming was IT when I was a lad - and Booch hadn't done his bit for the OO world at that stage - but there was Smalltalk to look at)

I've had a browse of design patterns etc.  And read extensively about OO, Patterns etc on-line (as much as is possible)

Perhaps I can talk the man-with-the-money here into getting me some upto date reference material ??


0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Alex, I'm not familar with the design patterns book, but the others are at the top of my list.  I'm starting one called C++ for real programmers by Jeff Alger.  It could be great.  Take up where scott meyers left of kinda thing.  Its too early to tell.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now