我有一个班级Game
,例如
class Game
{
public:
InitObjects();
...
};
我有另一个类Grid
,需要使用对该Game
对象的非const引用进行初始化。 (Grid
对象需要调用可以更新Game
对象的函数。
class Grid
{
public:
Grid(Game & g):
game(g){}
...
private:
Game & game;
...
};
Game
对象负责初始化Grid
。我这样做了:
void Game::InitObjects()
{
grid = new Grid(*(const_cast<Game*>(this)) );
}
grid
不是Game
的成员 - 它是全球性的(唉 - 我知道......我不介意让它成为会员,但我有同样的问题吗?) 。
有些经验丰富的C ++人可以告诉我这个奇怪的const_cast
是否可以接受?
答案 0 :(得分:2)
const_cast的主要问题是它违反了不对对象造成任何更改的承诺。它主要用于连接模块(C模块?),其中const不是一致使用的,你应该验证是否有任何变化。
一个替代方案可能是拥有一些可变成员,但当然,这些应该是可设计的(如锁,缓存),而不是方便(嘿,我想在对象发布为const时改变它。)
您的问题的问题是您的问题中没有任何常量,因此我认为不需要const_cast。
答案 1 :(得分:1)
鉴于InitObjects
不是const
,除非您在InitObjects
个实例上调用const Game
,否则无需const_cast
。虽然
答案 2 :(得分:1)
在我没有施展的时候,我看到了更多可怕的事情。
class A
{
private:
A * non_const_this;
public:
A() : non_const_this( this )
{
}
void changesme(); // non-const
void method() const
{
non_const_this->changesme();
}
};
我给出的上述代码是“我现在处于非const函数中,因此我将获取一个非const引用给自己,以便我可以在以后需要时更改对象,即使我在const上下文中也是如此”。这实际上比你可能的情况更糟(如果createObjects()是const),说“这个函数是const,因为它现在没有改变状态,但需要传递一个非const引用,因为我的状态会改变后”。
当然,首先比const修饰符更好的是拆分接口(对象的可变接口来自非可变对象)。
我在上面看到的是Game和Grid之间的一对一关系。 Grid引用了一个Game和Game的initObjects知道一个Grid。所以两者紧密耦合。这并不意味着它们应该是一个对象 - 再次分割界面 - 你可能想传递一个Grid&amp;或游戏&amp;仅供该类接口使用的参考。
是从构造函数调用InitObject吗?
答案 3 :(得分:0)
从对象构造不应该写入对象,因此您不会调用UB(通过写入您通过const_cast
解除的内容)。但是,这看起来很奇怪。特别是因为Game::InitObjects()
不是const
成员函数。为什么你认为this
指针是const
?!