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

时间:2014-07-16 18:36:01

标签: c++ inheritance iterator iteration stdmap

我们说我有一个Light课程,还有SpotLightPointLightDirectionalLight继承自Light

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

我想为每种类型迭代这张地图:

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

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

等...

我该怎么做?

4 个答案:

答案 0 :(得分:1)

你不能,你必须遍历每个项目并投射你想要的班级类型。

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

为了避免使用动态强制转换,您还可以向Light类添加函数,例如&#39; IsSpotLight&#39;可以通过SpotLight类重载以返回true等等。

您还可以为每种类型的灯制作单独的地图,因此如果您只需要聚光灯,请使用SpotLightMap映射。

答案 1 :(得分:1)

您可以使用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;
    }
}

答案 2 :(得分:1)

我已经编写了一些可以解决您需求的代码。

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;
            }
     }
}

如果它无法解决您的问题,请告诉我。我们将继续努力

答案 3 :(得分:0)

这样的东西
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 ++版本,请参阅here