Const_cast для этого указателя - я буду предупрежден другими программистами C ++ для этого? - PullRequest
0 голосов
/ 05 января 2011

У меня есть класс Game например,

class Game
{
    public:
        InitObjects();
        ...
};

И у меня есть другой класс Grid, который необходимо инициализировать с неконстантной ссылкой на этот Game объект. (Объект 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?

Ответы [ 4 ]

2 голосов
/ 05 января 2011

Основная проблема с const_cast заключается в том, что он нарушает обещание не вносить никаких изменений в объект. Это главным образом необходимо для взаимодействия с модулями (C-modules?), Где const не используется последовательно, и вы должны проверить, могут ли быть какие-либо изменения.
Альтернативой может быть наличие некоторых изменяемых членов, но, конечно, они должны изменяться по конструкции (например, блокировки, кэши), а не по удобству (эй, я хочу изменить это, когда объект выдан как const).

Проблема вашего вопроса в том, что в вашем вопросе нет ничего константного, поэтому я не вижу необходимости в const_cast.

1 голос
/ 05 января 2011

Я видел более ужасные вещи в свое время, вообще не читая.

class A
{
private:
   A * non_const_this;

public:

   A() : non_const_this( this )
   {
   }

   void changesme(); // non-const

   void method() const
   {
      non_const_this->changesme();
   }
};

Приведенный выше код, который я дал, звучит так: «Я нахожусь в неконстантной функции, поэтому я возьму неконстантная ссылка на себя, чтобы я мог изменить объект позже, когда мне нужно, даже когда я нахожусь в константном контексте ".Что на самом деле хуже, чем ваш возможный сценарий (если createObjects () является const), который говорит: «Эта функция является const, потому что она не меняет состояние сейчас, но должна передать неконстантную ссылку на себя, поскольку мое состояние изменитсяпозже ".

Конечно лучше, чем модификатор const, во-первых, был бы разделенный интерфейс (изменяемый интерфейс к объекту происходит от неизменяемого).

Что я смотрювыше отношения один-к-одному между Game и Grid.Grid имеет ссылку на одну игру, а initObjects игры знает об одной Grid.Таким образом, эти два очень тесно связаны.Это не обязательно означает, что они должны быть одним объектом - снова разделенным интерфейсом - вы можете передать Grid & или Game & reference для использования только интерфейса этого класса.

Вызывается ли InitObjects из конструктора?

1 голос
/ 05 января 2011

Учитывая, что InitObjects не является const, если только вы не вызываете InitObjects для const Game экземпляра, в const_cast нет необходимости.Я бы изменил эту круговую зависимость, хотя

0 голосов
/ 05 января 2011

Конструкция из объекта не должна писать в объект, поэтому вы не будете вызывать UB (что вы сделали бы, записав что-то, что вы удалили через const_cast). Тем не менее, это выглядит странно. Тем более, что Game::InitObjects() не является const функцией-членом. Почему вы думаете, что указатель this равен const?!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...