3

Well, I know the functionality of const data member in a C++ class.

What I want to know is, the purpose of introducing a const data member in a class. Why someone will use that while writing a real software? What are the real-life usage of const data members?

Please give me a few real life examples with reasons.

EDIT : I am not asking about static const data member. I am asking for some real life use cases where each object will be having a different const value for same data.

paper.plane
  • 1,201
  • 10
  • 17
  • 8
    For class invariants that are determined at construction time? – Kerrek SB May 09 '16 at 10:38
  • `constexpr static double pi = 3.14....` – uh oh somebody needs a pupper May 09 '16 at 10:44
  • 1
    @paper.plane could you give me a concrete example when you need to have a data member that it is not const? I would say that const is by default and not const are the exceptions – Alessandro Teruzzi May 09 '16 at 10:49
  • 1
    @AlessandroTeruzzi: Any object you plan to store in a standard container, for one. I agree with you in principle and I sprinkle `const` throughout my code with joy, but making the encapsulating class non-assignable is a substantial restriction. Besides, there are near-infinite potential useful classes whose state changes over time. – Lightness Races in Orbit May 09 '16 at 10:52
  • @LightnessRacesinOrbit I was pushing the envelop with my comment. In my defense, I have found the software community really skewed in favor of mutable objects (their drawbacks are widely underestimated IMHO). However, I agree, it is easier and more convenient to design an immutable object limiting its interface instead of setting data member to const. – Alessandro Teruzzi May 09 '16 at 12:21

3 Answers3

2

You'd use a const data member for the same reason that you'd use any const object: for a value that may be arbitrarily initialised but then never changed.

A good rule of thumb is to denote something as const "by default", so you can picture plenty of reasons to use it in a class.

class User
{
    User(const std::string& name)
      : name(name)
    {}

private:
    /**
     * User's name is an invariant for the lifetime of this object.
     */
    const std::string name;
};

Can you leave out the const here? Yeah, sure. But then you may accidentally change name when you didn't mean to. The entire purpose of const is to protect against such accidents.

However, sadly, your class will not be assignable!

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Yeah this is a good example. So, whenever you need a correction in your name which was wrongly mentioned in your bank records, you call up the customer care and then create another object with the correct name in constructor and call the assignment operator with the old object and then delete the old object. – paper.plane May 09 '16 at 11:02
  • @paper.plane: Well, if changing the name is legal and valid in your business logic, then you wouldn't use `const`. A "customer number" would probably have to be `const` though. – Lightness Races in Orbit May 09 '16 at 11:03
  • I agree with your point @Lightness , but I am just asking if the implementation is right when there is a change required, considering that changes in names are permitted. – paper.plane May 09 '16 at 11:06
  • @paper.plane: I'm not following. – Lightness Races in Orbit May 09 '16 at 11:24
1

There are several cases. The most obvious one is a static const data member. These are used as scoped constants:

class Something {
  static const int SOME_CONSTANT = 17;
};

Note that under C++11 and onward, constexpr usually makes more sense in those cases.

This defines a constant that is typed and scoped to the class' implementation. I suspect this was not what you were asking, however.

The more interesting use case is for values that are different between instances of the class, but constant across the class' lifetime.

For example, suppose you have a RAID implementation, where a configuration sets the stripe width. You do not know the stripe width at compile time, so the above construct will not help you. You do want the width to remain constant throughout the class' lifetime however (maybe your code doesn't know how to handle stripe width changes).

In those cases, marking the value const, and setting it in the constructor, can give you compile time guarantee that no one is changing this value.

Shachar Shemesh
  • 8,193
  • 6
  • 25
  • 57
  • Your logic is slightly flawed. Something can be different between instances of class even if it's `static constexpr`, i.e if it was initialized from a template argument. Furthermore, everywhere we expect to see `static const` would be `static constexpr` (constexpr implies const). A public `const variable` has no reason not to be `static constexpr` either. – uh oh somebody needs a pupper May 09 '16 at 10:54
  • I don't consider different instantiations of a class to be "the same class" (and neither do the compiler). As for the second comment, sometimes you want a "global" const that is only computable at runtime (such as the total amount of memory). I agree that often constexpr makes sense, and will amend the answer – Shachar Shemesh May 09 '16 at 10:59
0

You use it exactly the same as you would use a globally declared const, only you want it to only apply to the class you have defined it in. For example

class Character
{
public:
    Character()
    :
        mCurrentHealth{TOTAL_HEALTH},
        mCurrentMana{TOTAL_MANA}
    {
    }

    // Define lose/gain health/mana functions
    // for mCurrentHealth and mCurrentMana
private:
    int mCurrentHealth;
    int mCurrentMana;

    // Constants
    const int TOTAL_HEALTH = 100;
    const int TOTAL_MANA = 50;
};

There are many other examples, but the main point is that we don't want TOTAL_HEALTH and TOTAL_MANA defined outside the class, because they won't be relevant.

mojo1mojo2
  • 1,062
  • 1
  • 18
  • 28