由于我正在制作的游戏的性质,我需要能够随意创建对象。我需要能够每秒60次更改类的所有当前现有对象的变量。
我被告知虽然C ++无法反射,但我可以将对象的地址传递给向量。不幸的是,我对如何做到这一点感到有些困惑。有更好的解决方案吗?如果没有,有人可以提供示例代码吗?
TL;博士?我需要对类中所有对象的变量运行一个函数。 Howdo吗
答案 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
方法,该方法接受仿函数并将其应用于每个数据成员。
搜索访问者设计模式的堆栈溢出。