c++如何循环遍历不同的类型

C++ how to loop through different types

本文关键字:遍历 类型 循环 何循环 c++      更新时间:2023-10-16

假设我有一个Light类,还有SpotLight, PointLightDirectionalLight,它们继承自Light

我有一个灯的地图,像这样:std::map<std::string, Light*> LightMap;

我想为每个类型迭代这个映射,像这样:

for ( /* each SpotLight* in LightMap */ ) { ... }
for ( /* each PointLight* in LightMap */) { ... }

等等……

你不能,你必须遍历每一项,并强制转换为你想要的类类型。

for(std::map<std::string, Light*>::iterator iter = m.begin(); iter != m.end(); iter++)
{
    if (dynamic_cast<SpotLight*>(*iter))
    {
    }
}

为了避免使用动态强制转换,你也可以在你的Light类中添加像'IsSpotLight'这样的函数,它可以被SpotLight类重载以返回true,等等。

你也可以为每种类型的光制作单独的地图,所以如果你只需要聚光灯,使用SpotLightMap映射

您可以使用dynamic_cast和多态基类来确定您正在处理的光的类型:

#include <map>
#include <string>
#include <iostream>
class Light { public: virtual ~Light(){} }; // Light is polymorphic
class SpotLight : public Light {};
class PointLight : public Light {};
class DirectionalLight : public Light {};

int main() {
    using namespace std;
    map<string, Light*> lightmap;
    for (const auto& light : lightmap) {
        if (SpotLight* spot = dynamic_cast<SpotLight*>(light.second))
            cout << light.first << " is a spot light" << endl;
        else if (PointLight* point = dynamic_cast<PointLight*>(light.second))
            cout << light.first << " is a point light" << endl;
        else if (DirectionalLight* point = dynamic_cast<DirectionalLight*>(light.second))
            cout << light.first << " is a directional light" << endl;
        else
            cout << light.first << " is an unknown light" << endl;
    }
}

我已经写了一些代码来满足你的要求。

class Light {
    typedef enum {SpotLight, PointLight, DirectionalLight} LightTypeT;
    LightTypeT GetLightType() = 0;
};
class SpotLight : public Light {
    LightTypeT GetLightType() { return SpotLight; }
};

class PointLight : public Light {
    LightTypeT GetLightType() { return PointLight; }
};

class DirectionalLight : public Light {
    LightTypeT GetLightType() { return DirectionalLight; }
};
typedef std::map<std::string, Light*> LightMapT;
LightMapT::iterator be = light_map.begin(),
                    en = light_map.end();
for (; be != en; be++)
{
    Light * m_light = (*be).second;
    switch (m_light->GetLightType())
    {
        case SpotLight :
            {
                 // It is SpotLight
                 break;
            }
        case PointLight :
            {
                // It is PointLight
                break;
            }
        case DirectionalLight :
            {
                // It is DirectionalLight
                break;
            }
     }
}

如果这不能解决你的问题,请让我知道。我们会处理的

for ( /*each Light* lit in LightMap*/)
{
    //if lit is instance of Spotlight, do something
}
for ( /*each Light* lit in LightMap*/)
{
    //if lit is instance of PointLight, do something
}

有关instanceof的c++版本,请参阅此处