Вопрос о параметрах конструктора C ++ - PullRequest
2 голосов
/ 04 июня 2010

Я изучаю C ++. У меня есть простой класс с именем GameContext:

class GameContext {
    public:
        GameContext(World world);
        virtual ~GameContext();
};

Для инициализации объекта GameContext мне нужен объект World.

  • Если конструктор GameContext получает указатель на объект World (World*), адрес объекта World (&World) или ссылку Мир объекта (World)?

  • Что такое ключевое слово const при использовании рядом с параметром? Например: GameContext(const World &world)

Спасибо.

Ответы [ 7 ]

6 голосов
/ 04 июня 2010

Во-первых, терминология: вы правы, что World * будет указателем на объект World. A World &, однако, будет ссылкой на объект World. World будет копией объекта Мира, а не ссылкой на него.

const (используется в основном с указателем или ссылкой, как в World const &world или World const *world) означает, что вы получаете ссылку / указатель на объект const - другими словами, вы не разрешено изменять исходный объект, на который он ссылается / указывает.

Для небольших объектов вы обычно хотите передать копию. Для больших объектов вы обычно хотите передать константную ссылку. Есть исключения из этого, но это разумное практическое правило, пока вы не научитесь достаточно большему, чтобы знать, когда нарушать правила (так сказать).

Исходя из названия, я предполагаю, что ваш объект World, вероятно, достаточно велик, чтобы вы, вероятно, хотели передать его по константной ссылке, поэтому ваш ctor должен выглядеть следующим образом:

GameContext(World const &world);
4 голосов
/ 04 июня 2010

В идеале вы должны принять const ссылку на World:

class GameContext {
    public:
        GameContext(const World& world);
        virtual ~GameContext();
};

Во-первых, чтобы при передаче world не происходило копирования. Во-вторых, const - это ключевое слово, которое означает, что вы не собираетесь изменять переданный параметр, в данном случае world.

1 голос
/ 04 июня 2010

World не является ссылкой на объект World - компилятор создает копию структуры и передает ее через стек. Это плохо.

Указатель (World*) и ссылка (World&) очень похожи, они отличаются только синтаксисом (-> против .) и областью действия (вы не можете назначить ссылку, поэтому член m_pWorld не может указывать на другой Мир во время жизни вашего GameContext, если вы используете ссылку - но вы можете сделать это, если вы используете указатель). Мой совет: получите ссылку, если вы всегда будете использовать один и тот же Мир (скорее всего), или указатель в противном случае.

const указывает компилятору, что вы не будете изменять объект. Когда вы получаете ссылку на объект, вы работаете с объектом , а не с его копией - поэтому все, что вы изменяете в методе, фактически изменяет «внешний» объект. В вашем случае, поскольку вы, вероятно, будете изменять или иным образом работать с World в GameContext, вам, вероятно, понадобится неконстантная ссылка.

Так что вы должны сделать что-то вроде этого

class GameContext 
{
public:
    GameContext (World& pWorld) : m_pWorld(pWorld)
    {
    }

    virtual ~GameContext () { ... }

    void foo (int nParam)
    {
        m_pWorld.bar(nParam);
    }

private:
    World& m_pWorld;
};
1 голос
/ 04 июня 2010

Ваша терминология истекла.

В терминологии C ++ термины указатель и адрес являются синонимами (насколько мы говорим о значениях). Чтобы получить указатель (или адрес), вы должны объявить свой параметр как World* world.

Чтобы получить ссылку, параметр должен быть объявлен как World& world.

Чтобы получить скопированное значение, параметр должен быть объявлен как World world.

Какое заявление вы должны использовать в каждом конкретном случае, зависит от наших намерений. Предполагая, что World является нетривиальным объектом, выбор обычно должен быть ограничен либо ссылкой World& world, либо указателем World* world.

Если вы не собираетесь изменять исходный объект World в конструкторе GameContext, следует добавить const: const World& world или const World* world.

Наконец, передача по указателю позволяет передавать «зарезервированное» значение - нулевой указатель - но в то же время не позволяет передавать указатель на ненулевое значение. Если это не имеет большого значения для вас, то вам, вероятно, следует придерживаться ссылки const World& world.

0 голосов
/ 04 июня 2010

Если конструктор GameContext взять указатель на объект World (Мир *), обращение к Миру объект (и мир) или ссылка на Мир объекта (World)?

Прежде всего, «адрес объекта World» - это то же самое, что указатель на объект World. Указатель - это тип переменной, в которой хранится адрес объекта. Если вы передадите адрес, то параметр, соответствующий адресу, который вы передали, будет указателем.

Если вы хотите взять указатель или нет, зависит от семантики класса World. Если вы возьмете значение (а не указатель), то вы получите копию переданного объекта World. Если что-то, кроме объекта GameContext, должно выполнить операции над тем же объект мира, тогда вы захотите передать и сохранить указатель. Если в этом нет необходимости, или если класс World работает внутри системы так, что все копии объекта World используют общий набор данных, то вы можете передавать по значению.

Что такое ключевое слово const при использовании рядом с параметром? Например: GameContext (const Мир и мир)

const означает «не может быть изменено», так же, как и где-либо еще. Как обычно вы говорили в своем примере, в C ++ обычно используется постоянная ссылка вместо значения. Когда параметр является объектом (в отличие от фундаментального типа, такого как int или bool), это более эффективно, чем получение значения, поскольку в этом случае копия не создается. Однако const не позволяет функции изменять указанный параметр, поэтому для вызывающей стороны это не имеет значения, чем ссылка.

0 голосов
/ 04 июня 2010

const означает, что метод GameContext не сможет изменить содержимое параметра world

0 голосов
/ 04 июня 2010

Ссылка безопаснее указателей и не требует копирования. Что касается ключевого слова const, прочитайте ответ на этот вопрос, который я задал некоторое время назад: Сколько и как используется "const" в C ++?

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