首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >指向向量的指针不指向

指向向量的指针不指向
EN

Stack Overflow用户
提问于 2016-07-07 02:25:23
回答 3查看 78关注 0票数 0

我已经尽可能地简化了代码。所以我有两个类:

代码语言:javascript
复制
class EntityManager
{
    public:
        std::shared_ptr<std::vector<Entity> > getEntities()
        {
            return std::make_shared<std::vector<Entity> >(m_entities);
        }

    private:
        std::vector<Entity> m_entities{};
};

代码语言:javascript
复制
class System
{
    public:
        void loadEntities(std::shared_ptr<std::vector<Entity> > entities)
        {
            m_entities = entities;
        }

    private:
        std::shared_ptr<std::vector<Entity> > m_entities;
};

现在基本上我希望系统的m_entities指向EntityManager的m_entities。

我这样做了:

代码语言:javascript
复制
system = System();
system.loadEntities(m_entityManager.getEntities());

但是后来我将一个元素推回到EntityManager的m_entities向量中,而这个元素没有添加到System的m_entities向量中,这意味着我的指针没有指向。

我的错误在哪里?

谢谢!

EN

回答 3

Stack Overflow用户

发布于 2016-07-07 02:29:01

您的问题是这一行:return std::make_shared<std::vector<Entity> >(m_entities);

发生的事情是,shared_ptr管理一个新的std::vectory<Entity>容器,该容器被初始化为m_entities的副本。因此,在shared_ptr中修改实例不会修改EntityManager类中的数据成员,当然,shared_ptr也不会看到对EntityManager::m_entities所做的更改。

票数 2
EN

Stack Overflow用户

发布于 2016-07-07 02:36:59

std::make_shared不是“让这个东西被分享”,而是“让一个东西被分享”。

所以,你不能无中生有地创建一个指向已经存在的东西的共享指针。

您的代码动态分配一个从m_entities构造并由std::shared_ptr管理的std::vector副本。这是对此的简写:

代码语言:javascript
复制
std::vector<Entity>* ptr_to_copy = new std::vector<Entity>(m_entities);
return std::shared_ptr(ptr_to_copy);

不清楚你想要做什么,因为代码(你自己承认)并没有达到这个目标。但std::shared_ptr似乎不太可能适合这里。

如果是,则从一开始就动态分配和共享该向量;否则,只返回对该向量的引用。

票数 2
EN

Stack Overflow用户

发布于 2016-07-07 04:21:38

无指针解决方案的Hack示例。

代码语言:javascript
复制
#include <string>
#include <iostream>
#include <vector>

//Hack-sample Entity class
class Entity
{
    public:
        Entity(const char * name): m_name(name)
        {

        }
        void print() // this is stupid in real life. Prefer a << overload
        {
            std::cout << "Hi! I'm " << m_name << "!\n"; 
        }
    private:
        std::string m_name;
};

class EntityManager
{
    private:
        std::vector<Entity> m_entities;

    public:
        // hide the fact that a vector is being used to store the entities.
        // you can now swap out the vector for most standard containers without
        // changing any code other than the using and the declaration of m_entities
        using iterator = std::vector<Entity>::iterator;

        EntityManager(): m_entities({"bob", "bill"}) 
                         // just pre-loading a few test entities
        {
            // RAII says you should load the entities from their source here
        }
        // get the first entity. 
        iterator begin()
        {
            return m_entities.begin();
        }
        // get the end of the entity list
        iterator end()
        {
            return m_entities.end();
        }

        // adds an entity
        void addEntity(const Entity & entity)
        {
            m_entities.push_back(entity);
        }

        // removes an entity
        iterator removeEntity(iterator rem)
        {
            return m_entities.erase(rem);
        }

};

class System
{
    public:

        // example method to show System working with EntityManager by printing all of the Entities
        void printEntities()
        {
            for (EntityManager::iterator it = m_entityManager.begin();
                 it != m_entityManager.end();
                 ++it)
            {
                it->print();
            }
        }

        // example method to show System working with EntityManager by adding Entities
        void addMoreEntities()
        {
            m_entityManager.addEntity(Entity("Ted \"Theodore\" Logan"));
            m_entityManager.addEntity(Entity("Excellent!!!"));
        }

    private:
        EntityManager m_entityManager ;
};

// sample test
int main()
{
    System test;

    test.printEntities();
    test.addMoreEntities();
    test.printEntities();

}

这是一次黑客攻击。这只是一次黑客攻击。

如果你想做正确的EntityManager,请参阅Writing your own STL Container获取提示。如果你想要所有的细节,这项工作相当复杂。根据您使用EntityManager的方式和Entity管理逻辑的复杂性,您最好放弃EntityManager,只使用普通的、旧的std::vector

附录:What is meant by Resource Acquisition is Initialization (RAII)?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38231160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档