C++ 基于c+;中类中的参数查看私有变量的访问器方法+;?
我的问题是,我的类中有很多变量,我希望通过访问器方法访问它们。当然,我可以有几个访问器函数来输出我的私有变量,但是我怎样才能使它成为我可以通过一个参数访问它们中的任何一个呢。我的班级:C++ 基于c+;中类中的参数查看私有变量的访问器方法+;?,c++,oop,methods,private,accessor,C++,Oop,Methods,Private,Accessor,我的问题是,我的类中有很多变量,我希望通过访问器方法访问它们。当然,我可以有几个访问器函数来输出我的私有变量,但是我怎样才能使它成为我可以通过一个参数访问它们中的任何一个呢。我的班级: class Character { public: void setAttr(string Sname,int Shealth,int SattackLevel,int SdefenseLevel) { name = Sname; health = Shealth;
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教程都有一个函数来返回每个变量,这在大型程序中似乎是一件非常不健康的事情。我不知道这对您是否是一个好主意,但您可以使用公共typedef结构,通过引用传递并设置值
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++中有一个叫做“运行时类型信息”的东西,但是它不能提供关于变量名的信息:原因是,在编译和链接的二进制文件中,这个信息(变量的名称)不再是必须存在的。p> 但是,您可以使用简单的整数变量来完成类似的任务。因此,可以通过名称(如字符串)访问值。 请考虑以下代码:
#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;
}
另一个不依赖于无序映射的选项是,对变量名使用预定义的静态字符串,对值使用数组或向量。因此,我们可以将上面的类字符
替换为如下内容:
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];
};
另一个不相关的建议是:不要使用字符串作为函数的参数类型,而是使用
conststring&
(constreferencetostring;参见上面的示例代码)。这允许更轻松地调用函数(可以使用字符串文本直接调用它们,而无需在调用代码中创建其他变量),并且它们不会生成额外的不必要副本。唯一的副本将在:name=Sname代码>(在您的代码中出现了两个副本)。非常感谢!我知道我可以使用下面的代码来输出,但我在想,如果我有一个非常大的类,其中包含大量的变量,可能需要返回,那么这将需要很长时间来编码。我理解第二段代码,但对于第一段代码,值基本上像一个关联数组吗?编辑:我今天学习了指针和参考,它们让我很困惑。我唯一理解的是,引用可以在函数中使用,因此它可以操作主变量和别名(这就是您所做的)为什么要使用指针?我已经尝试了下面的代码,工作得非常出色,但我似乎无法让名称起作用!!。在头文件中,我声明了函数:string getName()const;在my Character.cpp中,我创建了一个方法:Character::getName{returnnewname;}。这与所有其他int方法一样。你知道为什么会发生这种情况吗。@mre12345在你的Character.cpp中你应该写字符串::getName const{return newName;}
-我想你错过了那里的const
。如果这并不能解决您的问题,请写出编译器给出的确切错误消息。很抱歉,如果时间太晚,因为我无法访问计算机,但我认为getName函数认为我想要返回int,即使我已将函数设置为返回字符串!!'。他是我的错误的打印屏幕:编辑:如果我在字符.h中生成整个函数,它将工作,但我听说这是一个糟糕的做法。@mre12345您的屏幕截图中缺少返回值string
。它应该是:string Character::getName const{return newName;}
,而不仅仅是Character::getName const{return newName;}
(否则编译器会错误地假定它是int
)
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];
};
#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;
}