对不同的 class 成员执行相同的操作,无需重复代码

Perform same operation on different class members without duplicate code

如何在不重复代码的情况下对不同的 class 成员执行相同的操作?

我有一个函数,它创建类型为 Farm 的对象,然后对其成员执行某种计算(在本例中,它打印成员变量,但我当前正在使用的代码on 太复杂了,无法完整复制到这里):

#include <iostream>
#include <String>

class Farm
{
public:
    int cows = 1;
    int chickens = 2;
    int mules = 3;
};

using namespace std;

void count_animals()
{
    Farm* animal_farm = new Farm;
    cout << animal_farm->chickens;
}

int main()
{
    string animals_to_count = "count my chickens";

    if (animals_to_count == "count my chickens")
        count_animals();
    if (animals_to_count == "count my cows")
        count_animals();
    if (animals_to_count == "count my mules")
        count_animals();

    return 0;
}

"Count my chickens" 硬编码在 main() 中。但是,在我现在正在处理的问题中,animals_to_count 将来自另一个函数作为参数。

是否可以打印 animal_farmcows/chickens/mules 而无需使用 count_animals 中的 n if 语句,其中n是成员变量的个数?

为了进一步澄清我的问题:我正在尝试做的是在 count_animals() 中有 1 个 if 语句,它将识别 Farm 的哪个成员被打印(更改 ->chickens->cows->mules).

我正在尝试的可能吗?如果没有,还有其他方法可以解决这个问题吗?

使用std::vector和常量索引:

class Farm
{
public:
    std::vector<int> animal_quantity(3);
    const int cow_index = 0;
    const int chickens_index = 1;
    const int mules_index = 2;   
};

当提到奶牛的数量时:

std::cout << animal_quantity[cow_index] << "\n";

将您的变量放入向量或其他容器中可能是正确的答案。

或者,您可以创建辅助函数(您可能希望私有或受保护),并且 getter 函数几乎没有代码。这使您可以一次编写复杂的统计信息提取,使用纤细的“getters”使其以您喜欢的方式可见。

class Farm
{
public:
    int cows = 1;
    int chickens = 2;
    int mules = 3;

    int get_cow_stats() {return get_complicated_thing(self.cows);}
    int get_chicken_stats() {return get_complicated_thing(self.chickens);}
    int get_mule_stats() {return get_complicated_thing(self.mules);}

private:
    int get_complicated_thing(int animals);
};

也许 pointer-to-member 就是您要找的东西?

#include <iostream>
using namespace std;

class Farm
{
public:
    int cows = 1;
    int chickens = 2;
    int mules = 3;
};

int Farm::* getMemberPtr(int whichMember)
{
    switch (whichMember)
    {
        case 0: return &Farm::chickens;
        case 1: return &Farm::cows;
        case 2: return &Farm::mules;
    }
    throw invalid_argument("");
}

void count_animals(int Farm::*member)
{
    Farm animal_farm;
    cout << animal_farm.*member;
}

int main()
{
    int animals_to_count = ...; // 0, 1, 2, etc
    int Farm::* member = getMemberPtr(animals_to_count);
    count_animals(member);
    return 0;
}

Online Demo