I have a class Game
e.g.
class Game
{
public:
InitObjects();
...
};
And I have another class Grid
, that needs to be initialised with a non-const reference to that Game
object. ( A Grid
object needs to call functions that can update a Game
object ).
class Grid
{
public:
Grid(Game & g):
game(g){}
...
private:
Game & game;
...
};
The Game
object is responsible for initialising the Grid
. I did this:
void Game::InitObjects()
{
grid = new Grid(*(const_cast<Game*>(this)) );
}
grid
is not a member of a Game
- it's a global ( argh - i know... I don't m开发者_StackOverflowind making it a member, but I have the same problem right? ).
Can some seasoned C++ folk tell me if this odd looking const_cast
is acceptable?
The main problem with const_cast is that it violates a promise of not causing any change to the object. It is mainly needed for interfacing with modules (C-modules?) where const isn't used consistently and you are supposed to verify whether there could be any change.
An alternative might be to have some mutable members, but of course, these should be mutable by design (like locks, caches), not by convenience (hey, I want to change this when the object issupposed to be const).
The problem with your question is that nothing is const in your question, so I don't see any need for const_cast.
I have seen more horrible things in my time without casting at all.
class A
{
private:
A * non_const_this;
public:
A() : non_const_this( this )
{
}
void changesme(); // non-const
void method() const
{
non_const_this->changesme();
}
};
The above code I have given is "I am in a non-const function now so I will grab a non-const reference to myself so I can change the object later when I need to even when I am in a const context". Which is actually worse than your possible scenario (if createObjects() is const) that is saying "This function is const because it is not changing the state now, but needs to pass out a non-const reference to self as my state will change later".
Of course better than the const modifier in the first place would be a split interface (mutable interface to an object derives from non-mutable one).
What I am looking at above is the one-to-one relationship between Game and Grid. Grid has a reference to one Game and Game's initObjects knows of one Grid. So the two are very tightly coupled. That does not necesasrily mean they should be one object - again split interface - you might want to pass a Grid& or a Game& reference for use of the interface of that class only.
Is InitObjects called from the constructor?
Given InitObjects
is not const
, unless you are calling InitObjects
on a const Game
instance, there is no need for the const_cast
. I'd be vary of that circular dependency though
Construction from an object should not write to the object, so you won't be invoking UB (which you would be by writing to something that you de-consted through const_cast
). However, this does look odd. Especially since Game::InitObjects()
is not a const
member function. Why do you think that the this
pointer is const
?!
精彩评论