Home > front end >  Perform same operation on different class members without duplicate code
Perform same operation on different class members without duplicate code

Time:10-28

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?

CodePudding user response:

Putting your variables into a vector or other container may be the right answer.

Alternately, you can make a worker function (that you may wish to be private or protected), and getter functions with almost no code. This lets you write your complicated statistics-extraction once, with slim "getters" that make it visible in your preferred way.

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

CodePudding user response:

Use std::vector and constant indices:

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

When referring to the quantity of cows:

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

CodePudding user response:

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

  • Related