C++ 如何创建具有未知成员函数的通用容器?
我注意到我经常需要一个容器类。例如,在处理粒子系统时,我创建了一个容器类C++ 如何创建具有未知成员函数的通用容器?,c++,algorithm,stl,containers,C++,Algorithm,Stl,Containers,我注意到我经常需要一个容器类。例如,在处理粒子系统时,我创建了一个容器类Particles,其中包含一个成员vector。然后我调用:Particles*my_Particleslikemy_Particles->draw(),在Particles.draw()中,我迭代向量,并再次对每个粒子调用draw()。这同样适用于成员函数,如update(),addforce()等。。现在,我正在做一个项目,需要一个Cube集合,我需要在其中调用tween(),movetoward()等 我知道我可以使
Particles
,其中包含一个成员vector
。然后我调用:Particles*my_Particles
likemy_Particles->draw()
,在Particles.draw()
中,我迭代向量
,并再次对每个粒子调用draw()
。这同样适用于成员函数,如update()
,addforce()
等。。现在,我正在做一个项目,需要一个Cube
集合,我需要在其中调用tween()
,movetoward()
等
我知道我可以使用模板,但对于模板类,成员函数需要事先知道。因为我想检查是否可以创建一个泛型类,例如,我可以使用我的立方体和粒子集合
有谁曾经这样做过,或者可以给我一些建议呢
亲切问候,,
Pollux我不确定我是否完全理解,但是每个
STL算法的会有帮助吗 我不确定我是否完全理解,但是for_each
STL算法是否有帮助简短的答案是,你不能在C++中这样做。但是,您可以使用STL算法和容器来包装这种行为
首先,将立方体或粒子实例放入std::vector
或其他容器中(就像现在一样)
然后,您将结合使用STL
结果会是这样的:
std::vector<Particle*> V;
V.push_back(new Particle);
V.push_back(new Particle);
V.push_back(new Particle);
V.push_back(new Particle);
std::for_each(V.begin(), V.end(), std::mem_fun(&Particle::draw));
std::vector V;
V.推回(新粒子);
V.推回(新粒子);
V.推回(新粒子);
V.推回(新粒子);
std::for_each(V.begin()、V.end()、std::mem_fun(&Particle::draw));
简短的答案是,你不能在C++中这样做。但是,您可以使用STL算法和容器来包装这种行为
首先,将立方体或粒子实例放入std::vector
或其他容器中(就像现在一样)
然后,您将结合使用STL
结果会是这样的:
std::vector<Particle*> V;
V.push_back(new Particle);
V.push_back(new Particle);
V.push_back(new Particle);
V.push_back(new Particle);
std::for_each(V.begin(), V.end(), std::mem_fun(&Particle::draw));
std::vector V;
V.推回(新粒子);
V.推回(新粒子);
V.推回(新粒子);
V.推回(新粒子);
std::for_each(V.begin()、V.end()、std::mem_fun(&Particle::draw));
据我所知,这里有一个设计问题,您希望使用同一个接口在不同的对象类别(立方体/粒子)上迭代,但很明显它们不能共享同一个接口,如果您真的想要,您必须实现tween()和movetoward()在抽象基类Particles和Cube上,在Particles类中没有实现任何东西。据我所知,这里有一个设计问题,您希望使用相同的接口迭代不同的对象类别(Cube/Particle),但很明显,它们不能共享相同的接口,如果您真的想要,您必须在Particles和Cube的抽象基类上实现tween()和movetoward(),而在Particles类中不实现任何内容。我读到您的问题:“我可以制作一个通用容器,用于多维数据集和粒子,即使它们具有不同的成员函数吗?”当然,这是最简单的部分。如果需要,您甚至可以将立方体和粒子放在同一个容器中。如果要处理指针,只需使用void*
:
std::vector<void*> objects;
objects.push_back(new Particle(...));
objects.push_back(new Cube(...));
即使你只在向量中存储粒子,比如说,你仍然需要向下转换才能使用它们:
for (i = objects.begin(), i != objects.end(), ++i) {
void* p = objects[i];
Particle* particle = dynamic_cast<Particle*>(p);
if (particle) {
// do particle stuff
} else {
// error!! I thought someone told me this thing only had Particles...
}
}
for(i=objects.begin(),i!=objects.end(),++i){
void*p=对象[i];
粒子*Particle=dynamic_cast(p);
if(粒子){
//做粒子的东西
}否则{
//错误!!我以为有人告诉我这东西只有粒子。。。
}
}
您可以看到,这样做比只将它们存储在单独的向量中要困难得多,因为在这些向量中,您知道每个向量中每个对象的类型,并且不必执行运行时向下转换来处理它们。这就是为什么这种容器通常被认为是低劣的风格
在这方面,你还可以考虑其他一些可能性,比如boost::any
或boost::variant
,它们可以处理指针以外的事情。我读到你在问:“我能不能制作一个通用容器,它可以用于立方体和粒子,即使它们有不同的成员函数?”当然,这是最简单的部分。如果需要,您甚至可以将立方体和粒子放在同一个容器中。如果要处理指针,只需使用void*
:
std::vector<void*> objects;
objects.push_back(new Particle(...));
objects.push_back(new Cube(...));
即使你只在向量中存储粒子,比如说,你仍然需要向下转换才能使用它们:
for (i = objects.begin(), i != objects.end(), ++i) {
void* p = objects[i];
Particle* particle = dynamic_cast<Particle*>(p);
if (particle) {
// do particle stuff
} else {
// error!! I thought someone told me this thing only had Particles...
}
}
for(i=objects.begin(),i!=objects.end(),++i){
void*p=对象[i];
粒子*Particle=dynamic_cast(p);
if(粒子){
//做粒子的东西
}否则{
//错误!!我以为有人告诉我这东西只有粒子。。。
}
}
您可以看到,这样做比只将它们存储在单独的向量中要困难得多,因为在这些向量中,您知道每个向量中每个对象的类型,并且不必执行运行时向下转换来处理它们。这就是为什么这种容器通常被认为是低劣的风格
在这方面,您还可以查看其他的可能性,包括boost::any
或boost::variant
,它们可以处理指针以外的事情。对于完整性,还有一些,尽管使用vector/for_是更好的解决方案。对于完整性,还有,尽管使用vector/for_是一个更好的解决方案。为什么不使用类似的方法:typedef std::vector Particles
然后void draw(Particles&p)
等等。?然后你可以做typedef std::vector Cubes
和void tween(Cubes&c,…)
。。。我想那是