2

Suppose I have a class with a member variable that I don't want to be changed. Is there any difference between making that variable a private const and just making the variable private, assuming there is no setter function?

Private:

class ConstFoo
{
public:
    Foo(int a);
    virtual ~Foo();
    int val(){ return val_; }
private:
    int val_;
}

Private Const:

class ConstFoo
{
public:
    Foo(int a);
    virtual ~Foo();
    int val(){ return val_; }
private:
    const int val_;
}

It seems that there is no difference between the two, since you can't change the value of val_ in either case, so the const qualifier seems redundant.

The one reason I can see to explicitly add const is for code clarity, so people working on the code in the future don't add a setter to the function. However, with the name as ConstFoo and documentation specifically stating that it is not meant to be mutable, I don't think this will be an issue.

Alex Jones
  • 226
  • 3
  • 13
  • You can change `int val` using some setter member function (method) in the first case, but not in second one. –  May 11 '18 at 20:17
  • make it like `int val() const { return val_; }` so that if you have `const ConstFoo foo;` or `bar(const ConstFoo& foo)` you are able to call `foo.val()` otherwise not. For the `val_` member, this is not really a big difference in the current context. – Victor Gubin May 11 '18 at 20:18

5 Answers5

13

It's all a matter of how "const" you want this value to be.

As it currently stands, no external user can directly change the value. But they can do so indirectly, because the object itself may not be const:

ConstFoo a{0};
ConstFoo b{2};
a = b;

a now has 2 in it.

Plus, code within ConstFoo can change its value too; this is why the copy assignment operator can change its value.

So if you want to ensure that the specific member object will assume one value throughout the lifetime of any ConstFoo instance, you declare it const.

Of course, this makes ConstFoo non-assignable.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • So if any member variable is declare as const, the assignment operator will no longer work? – Alex Jones May 11 '18 at 20:24
  • 2
    @AlexanderJ93: Not unless you write one. And even then, the written one can't change the `const` member. There is a distinction that needs to be made between mere "encapsulation" (outsiders cannot touch it) and "const" (*nobody* can touch it). – Nicol Bolas May 11 '18 at 20:31
7

You correct that no outsider can change the member if it is private. This does not mean though that it can't be changed. If you had another member function like

void bar() { val_ = 42; }

Then your first code block would compile while the second one would give you an error. If you truly do not want to be able to change the value of the member then it should be const regardless if it is private or not. That const will act as a bug checker for you.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
1

You've pretty much answered it yourself: making it const expresses your intention very clearly, and give the compiler the ability to back you up.

In my humble opinion, the const keyword serves two purposes:

A) It shows the programmers intent that this value is not to be changed once it's been set,

B) It allows the compiler to enforce that intent, thereby preventing mistakes.

Naming it constFoo somewhat achieves the first of these but does nothing for the second. And is (again IMHO) significantly more ugly than using const.

dgnuff
  • 3,195
  • 2
  • 18
  • 32
0

Not sure, if i get your question right, but generally speaking:

  • private members can only be accessed from inside the class itself, whereas public members can be accessed from the outside
  • const members can only be set once inside the constructor when creating a new object of this specific class

That means, a private const variable could be set once when creating a new object of this class and could therefor act as an internal modifier (e.g. giving a offset to certain functions provided by that class) valid over the whole lifetime of this object. A mere private variable could change its value from inside the class and therefor.

Also generally speaking you are completely right, the whole concept of using constants in C++ is for making sure, your constraints are complied to in the further development process (not only by other developers, also by yourself)

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
n00ne
  • 239
  • 1
  • 7
0

The private keyword makes sure noone outside the class can modify the variable.

If you don't modify the variable inside the class then the result is the same.

As my opinion it is better to use the keywork const too because not only it is telling to the developers (including yourself) who might modify your class that it is intended to remain constant but it is also more secure: if they try modify the modification will not have effect.

So in my opinion it is not redundant.

roschach
  • 8,390
  • 14
  • 74
  • 124