迭代类中的每个对象

时间:2011-10-04 23:20:04

标签: c++ class object foreach iteration

由于我正在制作的游戏的性质,我需要能够随意创建对象。我需要能够每秒60次更改类的所有当前现有对象的变量。

我被告知虽然C ++无法反射,但我可以将对象的地址传递给向量。不幸的是,我对如何做到这一点感到有些困惑。有更好的解决方案吗?如果没有,有人可以提供示例代码吗?

TL;博士?我需要对类中所有对象的变量运行一个函数。 Howdo吗

4 个答案:

答案 0 :(得分:3)

“将对象的地址传递给矢量”听起来像这样

std::vector<MyObject *> objectAddresses;

这是指向MyObject的指针向量。请注意,您必须手动添加和删除指针。

时,如果删除对象的指针未能从该向量中删除,则很容易导致程序崩溃。

根据性能需求,您可能希望选择除vector之外的STL容器。向量将使您的迭代非常快,但从向量中的任意位置移除对象将是昂贵的。如果不首先知道它在矢量中的位置,那也很困难。考虑一下std :: set。

http://www.cplusplus.com/reference/stl/列出了stl提供的容器,并粗略描述了它们的性能。

一旦你有了指针容器,只需在每个条目上循环并调用该函数。您可能需要两次解除引用,例如(* itor) - &GT; FUNC()

  

也许这只是你的术语,但我有多个对象,而且   我很困惑这是如何工作的。介意进一步深入?   我认为它应该更符合std :: vector objectAddresses;

如果您声明class MyClass,则应说vector<MyClass*>。如果您声明class MyObject,请说vector<MyObject*>。它与编译器相同,因此请使用对您更具可读性的那些。

std :: vector不是大多数图形程序员所认为的向量(例如,3个值表示3d空间中的位置)。它是一个自调整大小的数组。因此,当您向向量添加值(通过push_back方法)时,它将检查它是否已分配足够的内存来保存其他值,并在必要时重新分配更大的内存块。

class MyClass
{
  public:
    static std::vector<MyClass *> objAddrs;
    MyClass()
    {
      objAddrs.push_back(this);
    }
    ~MyClass()
    {
      // Find this in objAddrs & objAddrs.erase()
    }

    void doWork()
    {
      // something useful here
    }
};

将导致MyClass的每个实例在构造时将其自己的地址添加到objAddrs的末尾。请记住,析构函数必须删除相同的地址!

for(std::vector<MyObject *>::iterator itor=MyClass::objAddrs.begin(); itor!=MyClass::objAddrs.end(); ++itor)
{
  (*itor)->doWork();
}

将在MyObject()的每个现有实例上调用doWork()函数。如果任何MyObjects被破坏了析构函数无法删除它们,悬空指针将被取消引用&amp;将调用未定义的行为(可能是段错误)。

std :: set允许您按值删除:

class MyClass
{
  public:
    static std::set<MyClass *> objAddrs;
    MyClass()
    {
      objAddrs.insert(this);
    }
    ~MyClass()
    {
      objAddrs.erase(this);
    }
};

答案 1 :(得分:1)

我假设你想要一种迭代a的所有实例的方法 目前存在的课程没有经历麻烦 自己管理存储。 SelfStore旨在作为基础 这类功能的类。它内部使用list,因为我 假设经常创建和删除对象。你可能想要 切换到另一种更适合您的用例的存储类型。该 迭代器被保留为快速删除的成员,但可以完成 没有额外的存储是一个问题。这还需要一些 (很多)调整,例如私人存储和静态begin end,没有 可变访问,通过typedef等隐藏存储类型 不是线程安全的。 SelfStore只是一个模板,因为它可能会来 方便。

#include <iostream>
#include <list>

template<typename T>
class SelfStore
{
  typename std::list<SelfStore*>::iterator it;

public:
  SelfStore() {
    store.push_back(this);
    it = --end(store);
  }

  virtual ~SelfStore() {
    store.erase(it);
  }

  static std::list<SelfStore*> store;
};

template<typename T>
std::list<SelfStore<T>*> SelfStore<T>::store = std::list<SelfStore<T>*>();


struct Foo : public SelfStore<Foo> {

};


int main()
{
  {
  Foo f, g, h;
  std::cout << SelfStore<Foo>::store.size() << std::endl;
  }

  Foo a, b;
  std::cout << SelfStore<Foo>::store.size() << std::endl;
  return 0;
}

答案 2 :(得分:0)

在对象的构造函数中,将它们添加到全局的静态对象列表中(记得在析构函数中删除对象!)。这将让你找到对象并操纵它们。如果您的程序是多线程的,则需要一种方法来同步对列表和您正在操作的对象的访问。

答案 3 :(得分:0)

除非您的对象位于容器中,否则不能对数据成员使用标准迭代器或迭代循环。

我建议创建一个visitor方法,该方法接受仿函数并将其应用于每个数据成员。

搜索访问者设计模式的堆栈溢出。