c++member-variables

Perform same operation on different class members without duplicate code


How do I perform the same operation on different class members without duplicating code?

I have a function which creates an object of type Farm, and then performs some kind of a calculation on its members (in this case, it prints the member variable, but the code I am currently working on is too complex to copy here in its entirety):

#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" is hard-coded in main(). However, in the problem I am working on right now, animals_to_count will come from another function as an argument.

Is it possible to print cows/chickens/mules of animal_farm without using n if statements in count_animals, where n is the number of member variables?

To further clarify my problem: what I am trying to do is have 1 if statement in count_animals() which will identify which member of Farm is printed (change ->chickens to ->cows or to ->mules).

Is what I am trying possible? If not, are there other ways to work around this?


Solution

  • Perhaps a pointer-to-member is what you are looking for?

    #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