【问题标题】:C++ How can i modify a map from another class in a classC ++如何修改类中另一个类的映射
【发布时间】:2013-12-30 17:35:37
【问题描述】:

我有一个“Editor”类和一个“TileMap”类。

我希望能够使用我的 Editor 类修改我的 Tilemap 类,更具体地说是 Tilemap 类中的 std::map。

更清楚的是我不想这样做:

class Editor
{
private:
    std::map <int, tilemap> m_tilemap; // <--- i want this map

public:
    void target(std::map <int, tilemap> tilemap) // <---- to target this map
    {
        /*  ?   */
    }

    void putABlock(sf::Vector3i coord) // <---- and modify it through several methods...
    {
       /* modify the map */
    }

};

"tilemap",(带减 't')是一个结构体,有一个 int、一个 bool 和一个 sf::sprite。

我知道我可能不得不使用指针或引用,但我无法成功...

【问题讨论】:

    标签: c++ class map


    【解决方案1】:

    这里是你想要的代码:

    class Editor
    {
    private:
        // Use a pointer to the map
        std::map<int, tilemap>* m_tilemap;
    
    public:
        Editor()
        {
          // Set it to nullptr to avoid error in putABlock if it is called prior to
          // initialization
          m_tilemap = nullptr;
        }
    
        // Use reference to ensure that there is a tilemap passed. If it is optional
        // us a pointer void target(std::map<int, tilemap>* tilemap)
        void target(std::map<int, tilemap>& tilemap) 
        {
            // Assign the address of the tilemap to the pointer
            m_tilemap = &tilemap;
        }
    
        void putABlock(sf::Vector3i coord)
        {
            // Ensure here that we're working on something initialize.        
            if (nullptr == m_tilemap)
            {
                // Report error via one of the following method
                // 
                // * assert
                // * exeption
                // * log message
    
                return;
            }
    
           /* modify the map*/
           // Here some usage example:
           m_tilemap->insert(std::make_pair(...));
           (*m_tilemap)[...] = ...;
           (*m_tilemap)[...].tilemap_member = ...;
        }
    
    };
    

    但我认为你应该重新设计你的类,以便Editor 调用你的Tilemap 中的方法,而不是处理其他结构持有的东西。

    如果TilemapEditor 相比,我宁愿使用类似的东西:

    class Editor
    {
    private:
        // Use a reference to the map: the tilemap outlive the editor
        Tilemap& m_tilemap;
    
    public:
        Editor(Tilemap& tilemap) :
            m_tilemap(tilemap) // Initialize with the Tilemap already created
        {      
        }
    
    
    
        void putABlock(sf::Vector3i coord)
        {
            // No more test needed here
    
           /* modify the map */
           m_tilemap.methodOnTilemap(....);
        }
    
    };
    

    如果Tilemap 的寿命和我会做的编辑器一样:

    class Editor
    {
    private:
        // Use a instance of Tilemap 
        Tilemap m_tilemap;
    
    public:
        Editor(/* take potential params to create the tilemap */ ) :
            m_tilemap(/* feed the tilemap with the params*/ ) 
        {      
        }
    
        void putABlock(sf::Vector3i coord)
        {
            // No more test needed here
    
           /* modify the map */
           m_tilemap.methodOnTilemap(....);
        }
    
    };
    

    如果每个对象的相对活跃度很复杂,你应该看看std::shared_ptr&lt;&gt;

    如果你认为你真的需要直接修改std::map&lt;...&gt;,我关于活泼和 ref/pointer/shared_ptr 的建议仍然有效。

    【讨论】:

    • 谢谢,但我已经尝试过你的第一种方法,当我尝试修改 m_tilemap 时,它找不到任何成员。例如我做了“m_tilemap[0].block.setTexture(test);”编译器告诉我“class std::map ”没有名为 block 的成员。
    • @user3134405 如果您想在m_tilemap 中的索引0 处访问tilemap,请尝试(*m_tilemap)[0]。我更新了我的答案以澄清。
    • 谢谢它的工作!我稍后会尝试您的第二种方法。
    【解决方案2】:

    如果您希望在任何一种情况下都修改输入参数,您必须通过引用传递。

    void target(std::map <int, tilemap>& tilemap) // <---- to target this map
    {
        ?
    }
    
    void putABlock(sf::Vector3i& coord) // <---- and modify it through several methods...
    {
       /* modify the map */
    }
    

    您正在按值传递,因此制作了参数的副本,然后修改了副本而不是参数。是这个问题吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-03
      • 2013-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-08
      相关资源
      最近更新 更多