2014-08-31 3 views
0

StackOverflow!C++ - присвоение производному классу базовому классу

Я исхожу из насыщенного Java фона и впервые пытаюсь использовать его в C++. Я пишу базовый класс для представления состояния игры (состояние паузы, состояние воспроизведения, состояние меню). Класс Engine будет содержать ссылку на объект состояния, AKA - текущее состояние игры, а затем вызывает функции обновления состояния, рендеринга и pollIn состояния во время игрового цикла.

В Java, я хотел бы сделать это так:

В моем классе двигателей, я бы требовать моего текущего состояния переменной:

State currState = new MainMenuState(); 

Тогда, если бы я хотел, чтобы установить текущее состояние быть состояние Play, я мог бы просто сделать это:

currState = new PlayState(); 

Теперь, все, что я должен был бы сделать, чтобы убедиться, что мой двигатель вызова метода обновления правильного состояния является вызвать метод обновления текущего состояния, которая Я могу это сделать, потому что PlayState, MainMenuState и все мои другие состояния расширяют класс State, который имеет метод обновления.

public void update() 
{ 
currState.update(); 
} 

Как мне сделать что-то подобное на C++? Я решил определить все мои производные классы как общедоступные внутренние классы внутри класса State (мне нравится консолидировать код). Неужели для меня плохая практика иметь внутренние классы, расширяющие свой внешний класс?

мне еще нужно сохранить ссылку на текущее состояние в моем Engine, но я только что узнал о проблеме нарезания с назначением производного класса к базовому классу, как это:

State currState = new State::MainMenuState(); 

Так что, если я правильно понять, я не могу назначить производный класс объекту базового класса в C++, как я могу в Java. Итак, как мне сохранить один объект, который может содержать значения, представляющие все разные производные классы?

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация от меня. Заранее спасибо!

+0

std :: shared_ptr currState = ...; –

+0

Что такое shared_ptr? Извините, надеюсь, вы не возражаете, чтобы я спросил. Я довольно новичок в C++. Какие преимущества дает использование shared_ptr для регулярного указателя? – 13rave

ответ

3

Ну, вы только столкнулись с проблемой среза, если вы копируете объект. Чтобы достичь того, чего вы хотите, вы должны использовать указатели и виртуальные методы. Если вы назначаете указатель объекта derrived класса на указатель базового класса, вы в порядке. Так что State* currState = new State::MainMenuState(); должен работать нормально.

Или, как кто-то прокомментировал более современный подход, следует использовать общие указатели: std::shared_ptr<State> currState = std::make_shared<State::MainMenuState>();. std::shared_pointer инкапсулирует голый указатель и делает подсчет ссылок.

+0

Спасибо! Я попробую это :) – 13rave

+0

Ой, подождите, если у вас есть время ... У меня проблема, когда я пытаюсь это сделать, я получаю сообщение об ошибке «Нет жизнеспособного преобразования из« shared_ptr » to 'shared_ptr ' ".Могу ли я сделать что-то не так с моим наследством? в моем файле .h, я просто объявил класс MainMenuState общедоступным. Он ничего не наследует. В .cpp я указал, что «class MainMenuState :: public state». Это неверно? – 13rave

+0

Нет. Вы должны указать наследование в объявлении класса в файле заголовка. 'class MainMenuState: public State {...}'. – PovilasB

0

В дополнение к ответу @ PovilasB вы также спросили о внутренних классах. Вы можете использовать внутренние классы в C++, но это не так часто, как в Java. Лично я не помню, как последний раз я использовал внутренний класс на C++.