对不同的 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_farm
的 cows
/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;
}
如何在不重复代码的情况下对不同的 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_farm
的 cows
/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;
}