0

我有一个指向基本抽象类(实体)的指针列表

std::list<Entity*> m_entities;

我创建了一个 typedef 用于迭代这个类

typedef std::list<Entity*>::const_iterator entityIter;

然后我尝试遍历列表中的每个指针

for (entityIter i = m_entities.begin(); i != m_entities.end(); ++i)
{
    const Entity &e = *i;    // ERROR
    e.DoStuff();
}

尝试引用每个指针时出现以下错误

IntelliSense:不存在将“Entity *const”转换为“Entity”的合适构造函数

我做错了什么?

编辑:

我曾尝试使用 std::shared_ptr

std::list<std::shared_ptr<Entity>> m_entities;

我不能以这种方式添加到列表中

Entity::Entity(Game *game) 
    : m_game(game)                  
{
    m_game->g_idGenerator->generateNewID();

    m_game->m_entities.push_back(this);      // ERROR
}

使用以下

m_game->m_entities.push_back(std::shared_ptr<Entity>(this));

给我这个错误

错误 C2664: 'void std::list<_Ty>::push_back(_Ty &&)' : 无法将参数 1 从 >'Entity' 转换为 'std::tr1::shared_ptr<_Ty> &&'

编辑2:

当前代码摘要

for (entityIter i = m_entities.begin(); i != m_entities.end(); ++i)
{
    // *i dereferences the iterator and returns an Entity*
    // **i would additionally deference the pointer
    // Adding 'const' infront of Entity means that I can't alter the Entity
    Entity &e = **i;

    e.draw(dt);   // Causes access violation error with standard pointers
}   

已尝试转换为 std:shared_ptr 以查看是否可以避免上述代码触发的错误。

但是,我现在无法将实体添加到 std::shared_ptr 列表

    m_game->m_entities.push_back(std::shared_ptr<Entity>(this));

所以总而言之,我有一个标准指针的访问冲突错误,我不能用 shared_ptr 添加到列表中。

填充列表是通过基础实体类的构造函数完成的

Entity::Entity(Game *game) 
    : m_game(game)                  
{
    m_game->g_idGenerator->generateNewID();

            // shared_ptr version
    m_game->m_entities.push_back(std::shared_ptr<Entity>(this));  // ERROR C2664

            // raw pointer version
            //m_game->m_entities.push_back(this);  // ACCESS VIOLATION ERROR when calling methods
}
4

2 回答 2

13
const Entity &e = *i;

*i取消对迭代器的引用并返回一个 Entity*。

**i将另外尊重指针。

为避免保留参考,您可以使用(*i)->memberFunction(...);

不要忘记,如果您分配了实体operator new,您也需要operator delete它们。

这是一个使用示例,std::shared_ptr因为您的代码看起来很复杂,无法在页面上讨论。

我创建了一个简单的Entity类并在std::shared_ptr. 我std::shared_ptr<Entity>多次放置相同的内容纯粹是为了演示std::shared_ptr管理这些信息,包括将自身复制到列表中。

#include <memory>
#include <iostream>
#include <string>
#include <list>
using namespace std;

class Entity {
private:
  string name;
public:
  Entity(const std::string& n) :
    name(n)
  { }

  const string& getName() {
    return name;
  }
};

int main(int argc, char** argv) {
  list<shared_ptr<Entity> > l;

  shared_ptr<Entity> sp(new Entity("Repeated!"));

  l.push_back(sp);
  l.push_back(sp);
  l.push_back(shared_ptr<Entity>(new Entity("Foo")));
  l.push_back(sp);
  l.push_back(shared_ptr<Entity>(new Entity("Bar")));
  l.push_back(sp);

  for(list<shared_ptr<Entity> >::const_iterator iter = l.begin();
      iter != l.end(); ++iter)
    {
      cout << ">> " << (*iter)->getName() << endl;
    }
};

注意:将完全相同的原始指针放入多个std::shared_ptr对象和复制astd::shared_ptr之间存在差异push_back。后一种情况由完全管理,std::shared_ptr而前一种情况则各自std::shared_ptr试图独立管理。

于 2012-09-18T20:53:36.413 回答
2

选项 A)您想要访问元素并保证您不会更改它们:

typedef std::list<Entity*>::const_iterator entityIter;

std::list<Entity*> m_entities;
for (entityIter i = m_entities.begin(); i != m_entities.end(); ++i)
{
    const Entity &e = **i;    // ERROR
    e.DoStuff();
}

选项 B)您想要访问元素并更改它们:

typedef std::list<Entity*>::iterator entityIter; // no const_

std::list<Entity*> m_entities;
for (entityIter i = m_entities.begin(); i != m_entities.end(); ++i)
{
    Entity &e = **i;    // ERROR
    e.DoStuff();
}
于 2012-09-18T21:04:55.767 回答