如何在地图中访问矢量

时间:2016-05-28 04:26:38

标签: c++ dictionary vector

#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类中)?

3 个答案:

答案 0 :(得分: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;
};
虚拟dtor

Reason

<强> 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

接口是纯虚拟类(因为定义的每个方法都有&#39; = 0&#39;)。

第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();
}

您只能调用界面中的方法,因为地图中的类型是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...

但是,但......有什么东西丢失了吗? 东西似乎很奇怪......什么???我忘了使用删除??

好吧,我忘了整体使用c ++ 11来使这个例子变得更小,并保持我想要传达的内容。我应该使用的是std::unique_ptrstd::shared_ptr

&#39; new&#39; main看起来像这样,并在启用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等......具有不同的限制。但这是一个非常有效的问题,你应该调整这个&#34;模式&#34;以满足您的需求和理念。

希望它可以帮助您理解关于c ++ / c ++ 11和继承的一些概念,下一步是构建factory;)

答案 1 :(得分:0)

由于type被声明为protected,因此您无法正常访问该protectedfriend成员只能由public类或从类继承的人访问。最简单的解决方案是将变量声明为<Label row="2" col="1" text="USD {{ price }}" /> 。但它有自己的警告。

答案 2 :(得分:0)

首先,您应将type声明为public

然后,您应该board[index].front()->type

重要提示: index应该是char变量,因为地图board的密钥类型为char。< / p>

示例:

#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;
}