2016-05-28 2 views
0
#include <iostream> 
#include <string> 
#include <map> 
#include <vector> 
#include <cstdlib> 
#include <ctime> 

using namespace std; 
class ship 
{ 
    protected: 
    string type; 
    int size; 
    int hits; 
}; 
int main() 
{ 
    map< char,vector<ship*> > board; 
    for(int i=0;i<10;i++) 
    { 
     vector<ship*> v; 
     for(int j = 0;j<10;j++) 

     { 
      ship *s = new ship(); 
      v.push_back(s); 
     } 
     board['A'+i] = v; 
    }//set board 
} 

Я сделал map<char,vector<ship*> > доска. Как я могу получить доступ к type (в классе ship) от первого указателя корабля в первом элементе вектора на карте?Как получить доступ к вектору на карте

+0

* [C++] [карта] [вектор] * Дон» сделайте это. Для этого нужны теги. –

+0

Во-первых, вы не можете. 'type' защищен и' main() 'не является дружественным. Во-вторых, 'board ['A'] [0] -> type' предполагает, что вы исправляете первую проблему, но я сильно подозреваю темный горизонт. Удачи. – WhozCraig

+0

'vector v;' - Почему вы используете указатели здесь? Почему бы не просто 'vector v;' и пропустить все вызовы 'new'? – PaulMcKenzie

ответ

0

С type объявлен как protected, вы не можете нормально его получить. protected участников доступны только для классов friend или тех, кто наследует от класса. Самое простое решение - объявить переменные как public. Но у него есть свои оговорки.

0

Во-первых, вы должны объявить type как public.

Затем вы должны сделать board[index].front()->type

Важно:index должен быть char переменной, поскольку тип ключа карты board является char.

пример:

#include <iostream> 
#include <string> 
#include <map> 
#include <vector> 
#include <cstdlib> 
#include <ctime> 

using namespace std; 
class ship 
{ 
    public: 
    string type; 
    int size; 
    int hits; 
}; 
int main() 
{ 
    map< char, vector<ship*> > board; 
    for (int i = 0; i<10; i++) 
    { 
     vector<ship*> v; 
     for (int j = 0; j<10; j++) 
     { 
      ship *s = new ship(); 
      s->type = "Cannon ship"; 
      v.push_back(s); 
     } 
     board['A' + i] = v; 
    }//set board 
    cout << board['A'].front()->type << endl; 
} 
+0

Это вопрос личного вкуса, но я предпочитаю объявлять 'ship' как' struct', так как здесь нет методов. Тогда вам не понадобится ключевое слово 'public'. Также в цикле 'for' вы можете комбинировать три строки как:' v.push_back (новый ship {"Cannon ship"}); ' –

1

Хорошо, может быть, мой ответ будет немного над верхней частью, и это не совсем то, что вы спрашиваете, я знаю, но это может помочь вам понять, почему ценности в корабле защищены, и у меня слишком много времени.

Так как это очень распространенная проблема для создания игры вокруг кораблей/монстров/объектов, которые имеют общую базу методов и атрибутов, существует очень распространенный способ ее реализации. Он основан на трехуровневом наследовании.

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;)