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