2016-01-07 5 views
0

Может ли кто-нибудь предложить лучший дизайн для ситуации, когда мы хотим, чтобы два объекта «разговаривали» друг с другом через промежуточный промежуток const.Схема проектирования для доступа к неконстанту через промежуточное промежуточное звено

Вот надуманный пример, где два игрока торгуют лимонами. Игрок находит другого игрока в «мире», но «мир» должен быть 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 легко, но грязный. Или мы могли бы предоставить некоторый способ «поиска» ссылки на не-const Player, скажем, имея доступ к неконстантному player_list(), но здесь мы будем дублировать функции, уже имеющиеся в World, возможно, менее эффективно, все для круглый способ сделать конкретный const_cast.

+0

Я предполагаю, что вы можете захотеть заставить игроков «mutable» внутри вашего мира и вернуть им неконстантную ссылку. – SergeyA

+0

Мне кажется, что если мир концептуально содержит игроков, то изменение состояния игрока изменяет состояние мира. Я не могу придумать пример того, что вы пытаетесь сделать. Мне кажется, что вы хотите сделать некоторые функции * вызываемыми * (сменяющими игроков), но не другими. Итак, в каких контекстах могут быть вызваны другие функции? Может быть, ваш дизайн может быть лучше организован, если мир реализует несколько разных классов интерфейса *, каждый из которых подходит в разных контекстах? Затем, вместо того, чтобы передавать ссылку на мир, передайте ссылку на любой * класс интерфейса *, соответствующий – Galik

+1

'const' является неправильным в этом контексте, потому что вы * * изменяете состояние этих объектов. –

ответ

1

кажется, что оба Player и World можно рассматривать как актер

World случается быть const

Ввести Manager класс, обрабатывающий:

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 и не может иметь изменяемый список игроков, менеджер может.

+0

Я думаю, что это более уместно, так как я считаю, что коренной проблемой является то, что ваш «мир» может быть концептуально двумя разными вещами. Потому что ваш «игровой доски» вам может понадобиться const, но «состояние игроков», очевидно, должно измениться. Если вы не хотите, чтобы игроки обманывали, вам нужно, чтобы этот «менеджер» (аналогичный игровому мастеру) позволял изменять состояния игроков (например, лимоны ++/-) – mawalker

1

Наиболее прямым решением является сделать world.get_nearest_player() return a Player&, а не const Player&.

+0

Было бы невозможно, если бы игрок был членом мира (как я полагаю, это так). – SergeyA

+0

Я предпочел бы использовать 'std :: vector >' - но да. –