1

I'm an OOP newbie and just learning classes. Why can't I create constants and use them in classes without the static specifier? Like this:

class MyClass{
private:
   const int MyConst = 10;
   int MyArr[MyConst];
};

The compiler complains that:

invalid use of non-static data member ‘MyClass::MyConst’
'MyArr' was not declared in this scope

I checked out some tutorials, like C++ Primer Plus, which tells me to create an enumeration. Why do enumerations work? Don't they create constants like using the const qualifier?

3
  • 1
    You can. The problem is that non global integer constants can't be used for constant expressions which is what the array size requires. Commented Feb 4 at 4:02
  • 1
    A non-static one would be a waste of memory anyway. Why would you want an instance variable that always has the same value for all instances and never changes? A single variable that is common for all instances (that is, a static member) works just fine. If you want different constant values for different instances, you can have them, but then int MyArr[MyConst]; would make no sense because all class instances must have the same size known at compilation time. Commented Feb 4 at 5:51
  • Consider if MyConst was public and not private. You could then create an object of MyClass that initializes MyConst to a different value (even if it was declared const int). Or, you could define a constructor that initializes MyConst to a different value. C++ doesn't support dynamic C-style arrays in class declarations. Commented Feb 4 at 14:51

1 Answer 1

6

An array needs a constant expression for its size, such as a compile-time constant.

Without static, your MyConst value would be an instance member of MyClass. You would have to allocate an object instance of the class at runtime in order to access MyConst's value, as its location in memory would depend on where the object is allocated. So, you can't use MyConst as an instance member in a constant expression, even with the const. The const just means MyConst's value can't be changed at runtime after it has been initialized during the object's creation.

Making MyConst be static frees it from any particular instance of MyClass at runtime. It can now be referred to at compile-time. Added with const, that then allows the compiler to use MyConst's value in constant expressions.

An enum is a type. Its members have constant values at compile-time. So, you can a non-instance enum value wherever a constant expression is needed, without having to use static.

Sign up to request clarification or add additional context in comments.

2 Comments

I am surprised that static const int MyConst = 2; is considered "constant expression". Why isn't it required to be constexpr? E.g. const int can be initialized with runtime-dependent value like const int cn = rand()%10+1; or initialization can be moved to *.cpp, and only then compiler will complain.
@pptaszni • the static const int got grandfathered in as a constexpr, because the pattern predated constexpr being added to the language.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.