指向矢量的指针不指向
我尽可能简化了代码。 所以我有两个类:指向矢量的指针不指向
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{};
};
和
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。
我这样做:
system = System();
system.loadEntities(m_entityManager.getEntities());
但后来我推开一个元素的EntityManager的m_entities载体和系统的m_entities载体不添加这个元素,这意味着我的指针不指向。
我的错误在哪里?
谢谢!
你的问题是这样的一行:return std::make_shared<std::vector<Entity> >(m_entities);
正在发生的事情是,shared_ptr
管理新std::vectory<Entity>
容器,它被初始化为的m_entities
副本。因此,修改shared_ptr
中的实例不会修改EntityManager
类中的数据成员,当然shared_ptr
也不会看到对EntityManager::m_entities
所做的更改。
谢谢。有没有办法使用shared_ptr来解决它? – Urefeu
@Urefeu是的,但没有意义。你不需要共享指针。 – user4581301
@Urefeu为什么对shared_ptr的痴迷在这里? –
std::make_shared
没有“让这个东西分享”;它“会让事情分享”。
所以,你不能仅仅指出一个指向已经存在的东西的无处共享指针。
你的代码中动态分配std::vector
,复制从m_entities
构建和由std::shared_ptr
管理。这是速记本:
std::vector<Entity>* ptr_to_copy = new std::vector<Entity>(m_entities);
return std::shared_ptr(ptr_to_copy);
目前尚不清楚你想要做什么,从代码(由您自己也承认)没有实现这一目标。但在这里std::shared_ptr
似乎不太适合。
如果是,则从头开始动态分配和共享矢量;否则,只是返回一个对矢量的引用。
然后,我对使用不同的指针有点遗憾。我应该何时使用原始的,共享的,独特的...? – Urefeu
@Urefeu研究关于同一主题的其他问题,然后可能会问一个_new问题_。 –
@Urefeu涵盖在这里:http://*.com/questions/8706192/which-kind-of-pointer-do-i-use-when自这篇文章后,名称已经稍微改变,但逻辑仍然成立。 – user4581301
一个无指针解决方案的例子。
#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)?
简单的代码很好,但它仍然必须是完整的。再次阅读如何构建[MCVE]。 –
不要以为你需要一个共享指针。 'EntityManager'是实体列表的显而易见的所有者,它看起来像'System'拥有'EntityManager'。所有的所有权和生命期应该是已知的。 – user4581301
你应该知道什么意思?你有什么建议使用? – Urefeu