遍历类c ++的对象

时间:2018-11-27 12:51:15

标签: c++ loops class object

所以我有一个包含120个对象的类,每个对象都有相同的Member-Variables。 像这样:

Area f1;Area f2; Area f3; Area f4; Area f5; Area f6; [...]

f1.SetCoal(1);
f2.SetCoal(0.7); f2.SetCoal(.3);
f3.SetCoal(.5950); f3.SetCopper(0.2833); f3.SetIron(0.0917); f3.SetAmber(0.025); f3.SetGold(0.005);
f4.SetCoal(.5425); f4.SetCopper(0.325); f4.SetIron(0.1025); f4.SetAmber(0.0225); f4.SetGold(0.0075);
f5.SetCoal(.49); f5.SetCopper(0.3667); f5.SetIron(0.1133); f5.SetAmber(0.02); f5.SetGold(0.01);
f6.SetCoal(.4375); f6.SetCopper(0.4083); f6.SetIron(0.1242); f6.SetAmber(0.0175); f6.SetGold(0.0125);  [...]

因此,这些区域中的一些区域通过用户输入而变为“活动”,将成员变量设置为TRUE。是否可以遍历所有对象并检查它们是否处于活动状态?

for (int i = 0; i <= 119; i++)
{

     if(f(i).active == true) 
     //do stuff
}

代替

if(f1.active) //do stuff
if(f2.active) //do stuff
if(f3.active) //do stuff

3 个答案:

答案 0 :(得分:2)

您可以对所有区域进行std::vector,并使用初始化列表将其初始值初始化。然后,您可以使用基于范围的for循环遍历它们。

#include <vector>

class Area {
    double m_coal;
    double m_copper;
    double m_iron;
    double m_amber;
    double m_gold;

    bool m_active;
public:
    Area(double coal, double copper, double iron, double amber, double gold) :
        m_coal(coal), m_copper(copper), m_iron(iron), m_amber(amber), m_gold(gold), m_active(false)
    {}
    bool is_active() const { return m_active; }
};

int main() {
    // initialize all areas
    std::vector<Area> areas = {
        {1., 0., 0., 0., 0.},
        {0.7, 0., 0., 0., 0.},
        {.5950, 0.2833, 0.0917, 0.025, 0.005}
    };

    for (auto& area : areas) {
        if (area.is_active()) {
            // do stuff
        }
    }
}

如果您想更进一步,可以通过将资源放在std::array中来使其更容易处理。您可能需要一天扩展资源列表,如果这些资源到处都是硬编码的,那将非常耗时。更柔和的方法可能是这样的:

#include <iostream>
#include <initializer_list>
#include <array>
#include <vector>

// append to the list when you invent a new resource
enum Resource : size_t { coal, copper, iron, amber, gold, LAST=gold, COUNT=LAST+1 };

class Area {
    std::array<double, Resource::COUNT> m_resources;
    bool m_active;
public:

    Area(std::initializer_list<double> il) :
        m_resources(),
        m_active(false)
    {
        std::copy(il.begin(), il.end(), m_resources.begin());
    }

    double get(Resource x) const { return m_resources[x]; }
    void set(Resource x, double value) { m_resources[x]=value; }
    void add(Resource x, double value) { m_resources[x]+=value; }

    void set_active() { m_active=true; }
    void set_inactive() { m_active=false; }
    bool is_active() const { return m_active; }
};

int main() {
    // initialize all areas
    std::vector<Area> areas = {
        {1.},
        {0.7},
        {.5950, 0.2833, 0.0917, 0.025, 0.005},
        {.1232, 0.3400, 0.0000, 0.234, 0.001}
    };

    areas[0].set_active(); // just for testing
    for (auto& area : areas) {
        if (area.is_active()) {
            // do stuff
            std::cout << "coal before: " << area.get(coal) << "\n";
            area.add(coal, -0.1);
            std::cout << "coal after : " << area.get(coal) << "\n";
        }
    }
}

答案 1 :(得分:0)

尝试这样的事情:

#include <vector>

std::vector<Area> f(120);

f[0].SetCoal(1);
f[1].SetCoal(0.7); f[1].SetCoal(.3);
f[2].SetCoal(.5950); f[2].SetCopper(0.2833); f[2].SetIron(0.0917);
//...

for(auto & a: f)
{
     if(a.active == true) 
     //do stuff
}

答案 2 :(得分:0)

您可以使用C ++预处理程序,可能使用 Boost.Preprocessor 库扩展名:

$ yolk -M lxml -f summary,description
summary: Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.
description: lxml is a Pythonic, mature binding for the libxml2 and libxslt libraries.  It
provides safe and convenient access to these libraries using the ElementTree
API.

It extends the ElementTree API significantly to offer support for XPath,
RelaxNG, XML Schema, XSLT, C14N and much more.

...

请注意,这只是一个演示如何遍历名为#include <iostream> #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/arithmetic/inc.hpp> #include <boost/preprocessor/comparison/not_equal.hpp> #include <boost/preprocessor/repetition/for.hpp> #include <boost/preprocessor/tuple/elem.hpp> #define PRED(r, state) \ BOOST_PP_NOT_EQUAL( \ BOOST_PP_TUPLE_ELEM(2, 0, state), \ BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 1, state)) \ ) #define OP(r, state) \ ( \ BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 0, state)), \ BOOST_PP_TUPLE_ELEM(2, 1, state) \ ) #define INIT(r, state) \ BOOST_PP_CAT(x.var, BOOST_PP_TUPLE_ELEM(2, 0, state)) = \ BOOST_PP_TUPLE_ELEM(2, 0, state)); #define PRINT(r, state) \ std::cout << BOOST_PP_CAT(x.var, BOOST_PP_TUPLE_ELEM(2, 0, state)) << ", "; struct X { int var1, var2, var3, var4, var5; }; int main() { X x; BOOST_PP_FOR((1, 5), PRED, OP, INIT) BOOST_PP_FOR((1, 5), PRED, OP, PRINT) } 的(成员)变量,其中varI从1到5。您最终可以针对问题进行修改。

还请注意,这种解决方案非常丑陋且难以维护。我刚刚发布了因为它可以完成,但是强烈建议将这些变量存储为某种数组形式,如其他建议那样。

实时演示:https://wandbox.org/permlink/rpGg9iKVkrI3SCtM