通过 const 中间体访问非常量的设计模式
Design pattern for accessing non-const through a const intermediate
有人可以针对我们希望两个对象通过 const
中间体 "talk" 彼此的情况提出更好的设计。
这是一个人为的例子,两个玩家交易柠檬。
玩家在 "world" 中找到另一个玩家,但 "world" 应该是 const
,因为玩家不应该能够修改它(比如说删除墙)。
void Player::give_lemon()
{
const World& world = this->get_world();
const Player& other = world.get_nearest_player(*this);
this->lemons--;
other.lemons++; // error
}
人们用什么设计,一个简单的const_cast
很容易但很脏。
或者我们可以提供某种方式 "looking up" 非常量播放器引用,比方说通过访问非常量 player_list()
但这里我们将复制 World
中已有的功能,可能效率较低,所有这些都是为了以迂回的方式执行特定的 const_cast
.
最直接的解决办法是让world.get_nearest_player()
return变成Player&
,而不是const Player&
.
好像Player
和World
都可以看成演员
World
恰好是 const
引入一个 Manager
class 来处理:
Manager
将在其构造函数中使用 const World
,然后可以添加或删除 Player
。
void Player::give_lemon()
{
Manager& mgr = this->get_manager();
Player& other = mgr.get_nearest_player(*this);
this->lemons--;
other.lemons++; // error
}
然后管理器会跟踪玩家在其世界中的位置。 World
是 const
并且不能有可变的球员名单,经理可以。
有人可以针对我们希望两个对象通过 const
中间体 "talk" 彼此的情况提出更好的设计。
这是一个人为的例子,两个玩家交易柠檬。
玩家在 "world" 中找到另一个玩家,但 "world" 应该是 const
,因为玩家不应该能够修改它(比如说删除墙)。
void Player::give_lemon()
{
const World& world = this->get_world();
const Player& other = world.get_nearest_player(*this);
this->lemons--;
other.lemons++; // error
}
人们用什么设计,一个简单的const_cast
很容易但很脏。
或者我们可以提供某种方式 "looking up" 非常量播放器引用,比方说通过访问非常量 player_list()
但这里我们将复制 World
中已有的功能,可能效率较低,所有这些都是为了以迂回的方式执行特定的 const_cast
.
最直接的解决办法是让world.get_nearest_player()
return变成Player&
,而不是const Player&
.
好像Player
和World
都可以看成演员
World
恰好是 const
引入一个 Manager
class 来处理:
Manager
将在其构造函数中使用 const World
,然后可以添加或删除 Player
。
void Player::give_lemon()
{
Manager& mgr = this->get_manager();
Player& other = mgr.get_nearest_player(*this);
this->lemons--;
other.lemons++; // error
}
然后管理器会跟踪玩家在其世界中的位置。 World
是 const
并且不能有可变的球员名单,经理可以。