Хорошо, может быть, мой ответ будет немного над верхней частью, и это не совсем то, что вы спрашиваете, я знаю, но это может помочь вам понять, почему ценности в корабле защищены, и у меня слишком много времени.
Так как это очень распространенная проблема для создания игры вокруг кораблей/монстров/объектов, которые имеют общую базу методов и атрибутов, существует очень распространенный способ ее реализации. Он основан на трехуровневом наследовании.
1. Интерфейс
Он будет определить, какие методы могут быть вызваны извне, это контракт. Каждый класс, который наследует от него ДОЛЖЕН реализовать эти методы.
В вашем случае основная одна будет выглядеть следующим образом:
class IShip
{
public:
virtual ~IShip() // needs this, see link below
{ std::cout << "Interface destructor called" << std::endl; }
virtual std::string type() = 0;
virtual int size() = 0;
virtual int hits() = 0;
virtual void specialMove() = 0;
};
Reason для виртуального dtor.
2. Аннотация
Он наследует от этого интерфейса, и реализовать основные методы, которые Многоразовые на каждом корабле, это может быть сделано таким образом:
class AShip : public IShip
{
public:
AShip(std::string type, int size, int hits)
: _type(type)
, _size(size)
, _hits(hits)
{ std::cout << "Abstract constructor called" << std::endl; }
virtual ~AShip() // still needs this
{ std::cout << "Abstract destructor called" << std::endl; }
virtual inline std::string type() // inline keyword to put the code in-place instead of calling it
{ return _type; } // should only do this on very small methods
virtual inline int size() // virtual are not necessary
{ return _size; } // but it's best practice to clarify code
virtual inline int hits()
{ return _hits; }
// -- need overload method
virtual void specialMove() = 0;
// -- protected since it needs to be accessible from child classes
protected:
std::string _type;
int _size;
int _hits;
};
На данный момент вы не можете создавать что-либо, потому что оба эти класса являются виртуальными. More about virtual classes
Интерфейс, являющийся чистым виртуальным классом (потому что для каждого метода определены «= 0»).
3.Instanciable
Что вы можете сделать сейчас реализовать легко несколько классов, которые наследуются от AShip но еще указать что-то особенное, вы правы, я говорю о specialMove, я создам два класса ради мой пример:
class TheDestructor : public AShip
{
public:
TheDestructor()
: AShip("The Destructor", 20, 100)
, _attack("DestructionOver9000")
{ std::cout << "TheDestructor constructor called" << std::endl; }
virtual ~TheDestructor() // still needs this to help the compiler
{ std::cout << "TheDestructor destructor called" << std::endl; }
inline void specialMove() // specialMove overload
{ std::cout << "Attack " << _attack << " from " << _type << std::endl; }
private:
std::string _attack;
};
class MyPunyShip : public AShip
{
public:
MyPunyShip()
: AShip("My Puny Ship", 1, 1)
, _escape("just fly away as fast as he can...")
{ std::cout << "MyPunyShip constructor called" << std::endl; }
virtual ~MyPunyShip() // still needs this to help the compiler
{ std::cout << "MyPunyShip destructor called" << std::endl; }
inline void specialMove() // specialMove overload
{ std::cout << _type << " " << _escape << std::endl; }
private:
std::string _escape;
};
Теперь давайте проверить то, что было сделано:
int main()
{
std::map<std::string, IShip*> ships;
ships.insert(std::make_pair("The Destructor", new TheDestructor));
std::cout << std::endl;
ships.insert(std::make_pair("My Puny Ship", new MyPunyShip));
std::cout << std::endl;
for (std::map<std::string, IShip*>::iterator itS = ships.begin() ; itS != ships.end() ; ++itS)
{
// *itS to access the data of the iterator
// second to access the second member of the pair
std::cout << "type: " << (*itS).second->type() << "\n";
std::cout << "size: " << (*itS).second->size() << "\n";
std::cout << "hits: " << (*itS).second->hits() << "\n";
std::cout << std::endl;
}
ships["The Destructor"]->specialMove();
ships["My Puny Ship"]->specialMove();
}
Вы можете вызывать только методы, которые находятся в интерфейсе, так как тип в карте есть n IShip, но он позволяет вам реализовывать различные суда с различной статистикой.
давайте посмотрим, что выход ...
Выход:
Abstract constructor called
TheDestructor constructor called
Abstract constructor called
MyPunyShip constructor called
type: My Puny Ship - size: 1 - hits: 1
type: The Destructor - size: 20 - hits: 100
Attack DestructionOver9000 from The Destructor
My Puny Ship just fly away as fast as he can...
Но, но ... Что-то не хватает правильно? Что-то кажется очень странным ... Что ??? Я забыл использовать delete ??
Ну, я забыл использовать C++ 11 в целом, чтобы сделать пример немного меньшим и сохранить то, что я пытался передать ясно. То, что я должен был здесь использовать, - или std::shared_ptr.
'Новый' главный будет выглядеть и компилировать с C++ 11 флаг включен:
int main()
{
std::map<std::string, std::shared_ptr<IShip>> ships;
ships.emplace(std::make_pair("The Destructor", std::shared_ptr<IShip>(new TheDestructor)));
ships.emplace(std::make_pair("My Puny Ship", std::shared_ptr<IShip>(new MyPunyShip)));
for (auto ship : ships) // damn that's neat...
{
std::cout << "type: " << ship.second->type() << " - ";
std::cout << "size: " << ship.second->size() << " - ";
std::cout << "hits: " << ship.second->hits() << "\n";
}
ships["The Destructor"]->specialMove();
ships["My Puny Ship"]->specialMove();
}
Выход:
Abstract constructor called
TheDestructor constructor called
Abstract constructor called
MyPunyShip constructor called
type: My Puny Ship - size: 1 - hits: 1
type: The Destructor - size: 20 - hits: 100
Attack DestructionOver9000 from The Destructor
My Puny Ship just fly away as fast as he can...
TheDestructor destructor called
Abstract destructor called
Interface destructor called
MyPunyShip destructor called
Abstract destructor called
Interface destructor called
Ничего себе, я так по тебе скучала C + +11. Шутка обособленно, вы можете видеть, что деструкторы автоматически вызывают наши указатели IShip *, довольно приятно, если вы спросите меня.
Почему интерфейс и реферат, похоже, переусердствовали? Я считаю, что для этого может понадобиться IVehicle, но создать AShip, ACar, ASpaceCraft и т. Д. С разными ограничениями. Но это очень важный вопрос, и вы должны адаптировать этот «шаблон» в соответствии с вашими потребностями и своей философией.
Надеется, что это может помочь вам понять несколько концепций на C++/C++ 11 и наследование, следующий шаг для вас, чтобы построить factory;)
* [C++] [карта] [вектор] * Дон» сделайте это. Для этого нужны теги. –
Во-первых, вы не можете. 'type' защищен и' main() 'не является дружественным. Во-вторых, 'board ['A'] [0] -> type' предполагает, что вы исправляете первую проблему, но я сильно подозреваю темный горизонт. Удачи. – WhozCraig
'vector v;' - Почему вы используете указатели здесь? Почему бы не просто 'vector v;' и пропустить все вызовы 'new'? –
PaulMcKenzie