在c++中查看类中基于参数的私有变量的访问方法
Accessor Method to view private variable based on argument in a class in c++?
我的问题是我的类中有许多变量,我希望通过访问器方法访问它们。当然,我可以有几个访问器函数来输出我的私有变量,但我如何才能使它能够通过参数访问它们中的任何一个。我的班级:
class Character {
public:
void setAttr(string Sname,int Shealth,int SattackLevel,int SdefenseLevel) {
name = Sname;
health = Shealth;
attackLevel = SattackLevel;
defenseLevel = SdefenseLevel;
}
int outputInt(string whatToOutput) {
return whatToOutput //I want this to either be health, attackLevel or defenseLevel
}
private:
string name;
int health;
int attackLevel;
int defenseLevel;
};
基本上我想知道的是如何返回一个关于outputInt函数的私有变量。大多数OOP教程都有一个函数来返回每个变量,这在大型程序中似乎是非常不健康的。
c++不支持你想要完成的事情:反射或关于对象的详细运行时信息。在c++中有一种叫做"运行时类型信息"的东西,但是它不能提供关于变量名的信息:原因是,在编译和链接的二进制文件中,这些信息(变量名)将不再必要出现。
但是,您可以使用std::unordered_map而不是普通的整数变量来完成类似的操作。因此可以通过名称访问值,作为字符串。请考虑以下代码:#include <string>
#include <iostream>
#include <unordered_map>
using namespace std;
class Character {
public:
void setAttr(const string& Sname, int Shealth, int SattackLevel, int SdefenseLevel) {
name = Sname;
values.insert(std::make_pair("health", Shealth));
values.insert(std::make_pair("attackLevel", SattackLevel));
values.insert(std::make_pair("defenseLevel", SdefenseLevel));
}
int outputInt(const string& whatToOutput) {
return values.at(whatToOutput);
}
private:
string name;
std::unordered_map<std::string, int> values;
};
int main(int argc, char* argv[]) {
Character yourCharacter;
yourCharacter.setAttr("yourName", 10, 100, 1000);
std::cout << "Health: " << yourCharacter.outputInt("health") <<std::endl;
std::cout << "Attack level: " << yourCharacter.outputInt("attackLevel") << std::endl;
std::cout << "Defense level: " << yourCharacter.outputInt("defenseLevel") << std::endl;
return 0;
}
它将按预期输出:
Health: 10
Attack level: 100
Defense level: 1000
另一个不依赖于unordered_map
的选项是,使用预定义的静态字符串作为变量名,使用数组或向量作为值。因此,我们可以将上面的class Character
替换为:
static std::string variableNames[3] = {
"health",
"attackLevel",
"defenseLevel"
};
class Character {
public:
void setAttr(const string& Sname, int Shealth, int SattackLevel, int SdefenseLevel) {
name = Sname;
variableValues[0] = Shealth;
variableValues[1] = SattackLevel;
variableValues[2] = SdefenseLevel;
}
int outputInt(const string& whatToOutput) {
int retVal = 0;
for (size_t i = 0; i < sizeof(variableNames)/sizeof(std::string); ++i) {
if (!whatToOutput.compare(variableNames[i])) {
retVal = variableValues[i];
}
}
return retVal;
}
private:
string name;
int variableValues[3];
};
仍然得到相同的输出。然而,这里你必须手动管理字符串数组中所有变量名的列表——我不喜欢这种解决方案,我个人更喜欢上面的其他解决方案之一。
在c++中处理这种设计的最常见的方法是使用单独的getHealth()
, getAttackLevel()
, getDefenseLevel()
函数代替。然而,这将错过一个用例,那就是:如果你想让用户输入一个字符串,比如"health"
,然后显示相应的变量,你需要自己编写代码来调用相应的getXXX()
函数。如果这在您的情况下不是问题,请考虑下面的代码,这将更加清晰:
#include <string>
#include <iostream>
using namespace std;
class Character {
public:
void setAttr(const string& Sname, int Shealth, int SattackLevel, int SdefenseLevel) {
name = Sname;
health = Shealth;
attackLevel = SattackLevel;
defenseLevel = SdefenseLevel;
}
int getHealth() const { return health; }
int getAttackLevel() const { return attackLevel; }
int getDefenseLevel() const { return defenseLevel; }
private:
string name;
int health, attackLevel, defenseLevel;
};
int main(int argc, char* argv[]) {
Character yourCharacter;
yourCharacter.setAttr("yourName", 10, 100, 1000);
std::cout << "Health: " << yourCharacter.getHealth() <<std::endl;
std::cout << "Attack level: " << yourCharacter.getAttackLevel() << std::endl;
std::cout << "Defense level: " << yourCharacter.getDefenseLevel() << std::endl;
return 0;
}
另一个不相关的建议:不要使用string作为函数的参数类型,而是使用const string&
(const reference to string;参见上面的示例代码)。这样可以更容易地调用你的函数(它们可以直接使用字符串字面量调用,而不需要在调用代码中创建额外的变量),而且它们不会产生额外的不必要的复制。唯一的复制将发生在:name = Sname;
(在您的代码中发生了两次复制)。
我不知道这对你来说是否是个好主意,但你可以使用一个公共类型的pedef结构,你通过引用传递并设置你的值。
class Character {
public:
//...
typedef struct allvalues{
string vname;
int vhealth;
int vattackLevel;
int vdefenseLevel;
}allvalues;
void getValues(allvalues& val){
val.vname = name;
val.vhealth = health;
val.vattackLevel = attackLevel;
val.vdefenseLevel = detenseLevel;
}
//...
};
//...
//somewhere in the code
Character myCarac;
//...
//Here how to use it
Character::allvalues values;
myCarac.getValues(values);
相关文章:
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 枚举环境变量的惯用C++14/C++17方法
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 从私有成员变量的成员方法返回unique_ptr
- 在派生类中使用基类的私有成员变量的最佳方法
- 打印所有继承的类成员变量和方法
- C++方法中的引用变量
- Visual C++: MSVC vs. GCC+CLANG: 处理 lambda 捕获类成员变量,正确的方法是什么?
- 有没有一种通用的方法来实现不变量
- 有没有将变量名称转换为双指针的简短方法?
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- C++中变量混叠的最佳方法
- 比较C++变量的最有效方法
- 使用类在C++中存储和列出变量/方法是否是一种好的做法
- 存储变量的更有效方法是什么?
- 对具有相同方法的不同类使用一个变量
- 如何使用另一个变量访问对象的变量/方法
- C++,静态局部变量(方法)与全局(文件)变量有什么区别
- Awesomium允许我在JS中调用/使用c++变量/方法吗?