Jump to content
  • Advertisement
Sign in to follow this  

mutable and const

This topic is 3274 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm not a big fan of the 'mutable' storage class specifier. However, it seems inevitable, for example in a sort of stream base class.
Quote:
class Stream
{
    virtual bool read(void* ptr, const int len) const { m_pointer += len; return true; }
    virtual bool write(const void* ptr, const int len) { m_pointer += len; return true; }

    mutable int pointer; // needs to be mutable to push the stream pointer in the read() method.
};
Is there any clean way round it (while still maintaining the read() method to be declared 'const').

Share this post


Link to post
Share on other sites
Advertisement
I can only imagine 2 other ways, both of which seem more unclean than a mutable variable:

* have a pointer/reference type: but Stream then depends on "third party storage"
* use, ahem, const_cast<>, or better, don't.

Note that a function being const shall not change the classes externally visible state, not its internal one. I guess streams are pretty borderline in this respect, because two consecutive reads with the same arguments might not yield the same return value. Dunno, I would prefer mutable.

[Edited by - phresnel on June 2, 2009 9:00:40 AM]

Share this post


Link to post
Share on other sites
const-correctness is about the immutability of the object's state, not its individual members. An object is considered immutable even if some internally used attributes change but the object's state appears to be unchanging from an external point of view. This is perfectly fine and there's no need to work around that.

Share this post


Link to post
Share on other sites
Quote:
Original post by phresnel
* use, ahem, const_cast<>, or better, don't.


Why? This is what I have traditionally used in the past to get around this kind of borderline area. Would making the variable mutable be a better approach?

Share this post


Link to post
Share on other sites
Quote:

const-correctness is about the immutability of the object's state, not its individual members. An object is considered immutable even if some internally used attributes change but the object's state appears to be unchanging from an external point of view. This is perfectly fine and there's no need to work around that.


right-o. I think I'll stick with it. It's one of the C++ quirks.

I prefer mutable on individual members, over type casts that discards type qualifiers, or not using a constant qualifier at all.

The 'read' function is just an example. Reading from a file, your are not modifying it (it can be read-only and still works). I suppose the analogy (probably wrong) would be a read-only file, but attributes can change (obviously, the write-protected flag needs to be modifiable).

The problem with const is that it has a domino effect. Once you use it somewhere, it is likely it will affect other function declarations.

Share this post


Link to post
Share on other sites
Any time you feel that some language construct does not work the way you would like is probably an indication that you're trying to do something wrong.

In this case, you've made some functions const yet they modify the state of your object. Fact is, reading and wring your stream modifies the state of your stream, so they are not candidates for being const functions. Simple as that. No need to use mutable.

If you're going to reinvent what the language provides for you you might consider benefitting from the experience and wisdom of those who designed the laguage. For example, C++ provides stream classes with read() and write() functions, and yet those functions of the standard classes are not const. Why not?

Share this post


Link to post
Share on other sites
I agree, read() isn't a const operation here. While conceptually the underlying data isn't modified, the position in the stream is.

Share this post


Link to post
Share on other sites
Quote:
Original post by _moagstar_
Quote:
Original post by phresnel
* use, ahem, const_cast<>, or better, don't.


Why? This is what I have traditionally used in the past to get around this kind of borderline area. Would making the variable mutable be a better approach?


I think the standard allows const_cast to reference and then changing the value of the referencee if the referencee happens to be non-const (i.e. not declared with const), but I personally think that const_cast's are plain ugly, the cast will always work (uninteded harddisk formatting or not), never mind whether the casted value is really const or not. But if I don't use const_cast, but instead declare the variable to be mutable, and then someday decide it shall no longer be mutable, the compiler will direct me to the points where I try to assign to it. But with a const_cast, if I happen to make some variable really const, the compiler won't bite me, and under uncertain conditions the application may crash.

Valid code:
class X {
int x;
void f () const {
const_cast<int&> (x)++;
}
};


But then, Joey finds that x'd better be const (even if he's missassuming something here):

class X {
const int x;
void f () const {
const_cast<int&> (x)++;
}
};


It still compiles, hopefully with a warning diagnostic, but it may crash freely during execution. Using mutable to state that you mean "x might change even in const function" might have prevented Joey from making it x const, because somebody else explicitly stated "x might change in const functions".

So, my opinion is that using const_cast for the sake of (alleged) const correctness is wrong, because there's potentially more trouble you can get in than with mutable.

Share this post


Link to post
Share on other sites
Quote:
Original post by oliii
The problem with const is that it has a domino effect. Once you use it somewhere, it is likely it will affect other function declarations.


Exactly. Begin soon with const-correctness, and imho, write RAII classes, which helps a lot with const-correctness (you can often make all members const if you don't have Init() or SetScreenSize(int,int) functions, but that is also POV).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!