Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const declaration inside the class

Tags:

c++

to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.

I'm having hard time understanding this:

class Y {
    const int c3 = 7;       // error: not static
    static int c4 = 7;      // error: not const
    static const float c5 = 7;  // error: not integral
    static const int c6 = 7;

};

How does const int c6 = 7; break following rule?

C++ requires that every object has a unique definition.

And static const int c6 = 7; do not break it (enums too)?

Please also explain why static const float c5 = 7; is not allowed but static const int c5 = 7; is allowed?

like image 218
Aayush Neupane Avatar asked Nov 08 '19 23:11

Aayush Neupane


People also ask

Can we initialize const variable in class in C++?

To initialize the const value using constructor, we have to use the initialize list. This initializer list is used to initialize the data member of a class. The list of members, that will be initialized, will be present after the constructor after colon. members will be separated using comma.

How do you declare a constant in a class in C++?

Const member functions in C++ Constant member functions are those functions which are denied permission to change the values of the data members of their class. To make a member function constant, the keyword “const” is appended to the function prototype and also to the function definition header.

Why do we use const in classes?

The const member functions are the functions which are declared as constant in the program. The object called by these functions cannot be modified. It is recommended to use const keyword so that accidental changes to object are avoided. A const member function can be called by any type of object.

What is const declaration?

A constant holds a value that does not change. A constant declaration specifies the name, data type, and value of the constant and allocates storage for it. The declaration can also impose the NOT NULL constraint. Topics.


1 Answers

A lot of these rules have been changing over time, so it really depends on the version of C++ you are using. Also, some of these may not be technically impossible, but the committee simply decided against them because they might be hard to implement, or are prone to errors. So you might not always get the most satisfying answer on why thing are the way they are.

Lets go over them one by one.

Const Member

class Foo
{
    const int bar = 7;
};

This used to be illegal before C++11. Before that version you were only allowed to initialize static variables in their declaration. If you are still not on C++11, my condolences. More details can be found here.

Static Member

class Foo
{
    static int bar = 7;
};

Another one that changed, but more recently. Before C++17 it was illegal to initialize non const static variables in their declaration. This has to do with the one definition rule. When the header containing this class is included in multiple translation units (.cpp files), which one should be responsible for initializing the value? This is why you have to place the definition somewhere in a single .cpp file.

After C++17 you are allowed to do this:

class Foo
{
    inline static int bar = 7;
};

When you use inline like this it somehow figures out how to only initialize it once. More details can be found here.

Static Const Float Member

class Foo
{
    static const float bar = 7.0f;
};

This has mainly to do with the unpredictability of floats when you run into floating point errors. An example:

class Foo
{
    static const float bar = 0.1f;
};

Since 0.1f is impossible to represent in most floating point implementations, you won't get exactly 0.1f, but only something very close to it. This can then result in different behaviors on different systems that have slightly different implementations, causing your program to run differently depending on the system.

This gets even worse when the value is the result of a calculation, because (a*b)*c is not guaranteed to be the exact same value as a*(b*c), even though it might seem like they are.

But const static floats are still allowed when you define the value outside of the class, so technically it would all still be possible to implement. But the committee never did, probably because it would cause more problems than it would solve. This is also similar to why you are allowed to use integral types as template parameters, but not floats.

template <int i> class Foo {}; // Good
template <float f> class Bar {}; // Bad

However, the committee seems to have changed it's opinion somewhat, since we are now allowed to use floats with constexpr. So it can be done if you write this instead:

class Foo
{
    static constexpr float bar = 7.0f;
};

Conclusion

All of these are actually possible in some form with the right version of C++ and the right syntax. Just keep in mind the potential issues described above, and you should be good to go.

like image 136
Rick de Water Avatar answered Oct 03 '22 21:10

Rick de Water