c++ - 如何访问 map 中的 vector

标签 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 类中)来自映射中 vector 的第一个元素中的第一艘船指针?

最佳答案

好吧,也许我的回答有点过头了,我知道这不是你真正要问的,但它可以帮助你理解为什么 ship 中的值受到保护,而且我似乎有太多时间。

由于围绕具有共同方法和属性基础的船只/怪物/对象构建游戏是一个非常常见的问题,因此有一种非常常见的方法来实现它。它基于三级继承。

<强>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。摘要

它继承了这个接口(interface),并实现了每艘船都可以重用的基本方法,可以这样做:

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

接口(interface)是一个纯虚拟类(因为定义的每个方法都有'= 0')。

<强>3。可实例化

你现在可以做的是轻松地实现多个继承自 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();
}

您只能调用接口(interface)中的方法,因为 map 中的类型是 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 .

"new"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* 指针调用的,如果你问我的话,这很好。

为什么 Interface 和 Abstract 看起来都做得过头了?我对此的看法是,人们可能需要一个 IVehicle,但可以创建 AShip、ACar、ASpaceCraft 等……但有不同的限制。但这是一个非常有效的问题,您应该调整此“模式”以适应您的需求和理念。

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

关于c++ - 如何访问 map 中的 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37495173/

相关文章:

c++ - 如何从 unique_ptr<Base> 的 vector 中获取派生迭代器?

java - 碰撞处理......困惑去哪里

c++ - 使用虚拟方法组织单例的最佳方式

c++ - Qt - 读取包含多个空字符的文件

python - python 3.7中使用matplotlib的黑噪声

python - 将图形转换为字典形式

vector - 如何使用unityscript在unity3d中定义一个vector3

c++ - 第一次使用 PCH,出现链接器工具错误

c++ - 具有未重写的纯虚拟析构函数的类是否应该可初始化?

c++ - 如何打印 map 内容数据类型是类对象