Constant

This is a discussion on Constant within the C++ Programming forums, part of the General Programming Boards category; Code:
returntype functionName(const testClass& obj);
returntype functionName(testClass& obj) const;
What is the difference between having const inside the argument list ...

Manasij Mukherjee | gcc-4.9.2 @Arch Linux Slow and Steady wins the race... if and only if :1.None of the other participants are fast and steady.
2.The fast and unsteady suddenly falls asleep while running !

The first one applies const to the variable; that is, you can't change the variable state (or contents), or call non-constant member functions if there are any.
In the second case, the effect is the same as applying const to all member variables and allow calls only to const member functions.

The first one says, "This function shall not modify this argument."
The second one says, "This function shall not modify this instance."*

*) Well, you can make an exception with the mutable keyword. Google it if you're interested, but use it with care.

If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

The first one applies const to the variable; that is, you can't change the variable state (or contents), or call non-constant member functions if there are any.
In the second case, the effect is the same as applying const to all member variables and allow calls only to const member functions.

The first one says, "This function shall not modify this argument."
The second one says, "This function shall not modify this instance."*

*) Well, you can make an exception with the mutable keyword. Google it if you're interested, but use it with care.

So in the first one you can use the argument in calculations and such, but you just can't change it, right? I'm not quite sure on what the second one means.

mutable is a hack, actually. The only justification is that, without it, programmers use uglier hacks (casting away const, for example) to achieve the same effects.

Making an object or its member function const merely says that "we shall not change any non-static members of that object unless they are mutable".

I'm not sure I would call it a hack. It's a feature. It may look ugly, but it has its uses and can be quite useful at times. Just like goto (though I don't have any good uses for that one).

Originally Posted by UserName112

So in the first one you can use the argument in calculations and such, but you just can't change it, right? I'm not quite sure on what the second one means.

The second one means that if you have a Ford and call a member function, then the Car shall not be a Ferrari after the function call is done.
Obviously, to transform a Ford to a Ferrari, you need to change member data in that object, and we won't allow that.

I actually have a problem with mutable in that examples of its use seems so contrived to me. Example, my textbook paints a picture we're supposed to imagine: a window object -- unimplemented by the text's author, of course -- who's scrollbar size is constant (why?) but it can change if the user resizes the window, so it's mutable. Features that have dubious uses aren't worth mentioning.

Consider the case if you want to make your object thread-safe and no mutable.
The alternative would be to force the client code to take care of thread safety for the object instead of the object itself.

Example, my textbook paints a picture we're supposed to imagine: a window object -- unimplemented, of course -- who's scrollbar size is constant (why?) but it can change if the user resizes the window, so it's mutable.

That sounds like the author does not understand what the mutable keyword is for. If the scrollbar size is constant, then the scrollbar size is constant, and using mutable does not change that. In fact, I did a quick test, and both the MinGW port of g++ 3.4.5 and the Comeau online compiler refused to compile code that declared a const member variable mutable.

mutable was designed for those cases where the object is accessed in a context where it is constant (e.g., it was passed by const reference), but certain member variables may need to be updated while maintaining logical constness.

For example, you might provide a member function that caches and returns some computed property. You only compute this property if a dirty flag is set. Now, if this member function is called from within a context where the object is const, it makes sense if the dirty flag is set to compute this property, cache the result, and unset the dirty flag, then return the result. To the user, it would appear to be the same as if you did this prior to passing the object to this context where it is const (e.g., by performing and caching the computation instead of setting the dirty flag). Therefore, logical const correctness is maintained, hence both this cache and the flag should be declared mutable.

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.

Well, that doesn't really help... I mean objects don't have to be thread safe for stuff like semaphores to work. We're getting into a design argument and I don't want that. I had to express my frustration. Mutable is tersely talked about which leaves me confused. Going back to my original example -- you know -- what does scrollbar size even mean? I wish people would stop sometimes because mutable is about as hard to use as volatile.

edit - @laserlight: You were typing while I was typing, but thanks for explaining.

I may have cast judgement too early though: are you sure that your textbook has the window size set as a mutable const member variable, or as a mutable non-const member variable returned through a const member function?

If the latter, then the textbook example makes sense in precisely the same way I described: the scrollbar size should be returned through a const member function since calling that function does not change the size, from the user's point of view. However, if the actual size was changed prior to calling that function, yet the cached size was not yet updated, then the size should be changed, though to the user it hasn't. Yet, in the context of the const member function, the entire object, including the size, is constant. What to do? Declare the size as mutable, so it can still be updated.

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.

It was a mutable non-const string in fact. I didn't even remember right.

This is a transcription of the section on mutable. I make some remarks in pink or something, just so its clear why and how I'm confused.

Ordinarily, when you create a const object (as described in Chapter 6), you want a guarantee that none of its member data can be changed. However, a situation occasionally arises where you want to create const objects that have some specific member data item that needs to be modified despite the objects constness.

As an example, let's imagine a window (the kind that Windows programs commonly draw on the screen). It may be that some of the features of the window such as its scrollbars and menus and are owned by the window. Ownership is common in various programming situations, and indicates a greater degree of independence than when one object is an attribute of another [what?]. In such a situation an object may remain unchanged, except that its owner may change. A scrollbar retains the same size, color, and orientation, but its ownership may be transferred from one window to another. It's like what happens when your bank sells your mortgage to another bank; all the terms of the mortgage are the same, but the owner is different.

[mutable.cpp is here]

The size attribute represents the scrollbar data that cannot be modified in const objects. The owner attribute, however, can change, even if the object is const. To permit this, it's made mutable. In main we create a const object sbar. Its size cannot be modified, but its owner can, using the setOwner() function. (In a non-const object, of course, both attributes could be modified.) In this situation, sbar is said to have logical constness. That means that in theory the object can't be modified, but in practice it can, in a limited way.

That's all. A lot confused me here since the example was not what I wanted to see and he's pretending I understand mortgages to the degree he apparently does. With all these concepts, complicated in their own right, piled on to explain this... I just didn't get it. Plus there could be something wrong with what he wrote beyond my complaints.

The owner attribute, however, can change, even if the object is const. To permit this, it's made mutable. In main we create a const object sbar. Its size cannot be modified, but its owner can, using the setOwner() function. (In a non-const object, of course, both attributes could be modified.) In this situation, sbar is said to have logical constness. That means that in theory the object can't be modified, but in practice it can, in a limited way.

I don't buy this. "Logical constness" is about the observable state of the object, i.e., pick some member function foo that allows you to observe something about an object. Call any const member function, then call foo, and the result of calling foo should be the same as before the call of the const member function. Clearly, in this author's example, a call to getOwner may return "owner A", then after setOwner("owner B"), a call to getOwner will return "owner B", not "owner A", despite the fact that setOwner is a const member function.

In my opinion, if we are to model a window that owns a scrollbar, then it is the window object that should contain the scrollbar object, e.g., through some kind of list of (smart) pointers to components, where a scrollbar is a component. If the scrollbar really needs to be aware of its owner, then this should be done through a (smart) pointer such that if you want to change the owner, you may obtain a pointer to the owner from the scrollbar, and then you change the owner through the pointer, not through the scrollbar.

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.