指向矢量的指针不指向
Pointer to a vector doesn't point
我已经尽可能地简化了代码。所以我有两个类:
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指向实体管理器的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
所做的更改。
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
在这里似乎不太可能合适。
如果是,则从一开始就动态分配和共享向量;否则,只需按原样返回对向量的引用。
无指针解决方案的黑客示例。
#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
,请参阅编写自己的 STL 容器以获取提示。如果你想要所有的花里胡哨的东西,这项工作相当复杂。根据您使用EntityManager
的方式以及Entity
管理逻辑的复杂性,您最好丢弃EntityManager
,只使用普通的旧std::vector
。
附录:资源获取是什么意思是初始化(RAII)?
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错