C++ 串池/实习-这是一种良好的做法吗?
例如,我有一个类,我正在二进制文件中存储有关该类的一些信息:C++ 串池/实习-这是一种良好的做法吗?,c++,C++,例如,我有一个类,我正在二进制文件中存储有关该类的一些信息: class car { char car_manufacturer; //other stuff }; 其中,car\u manufacturer的值为下列值之一: enum car_manufacturers : char { VOLVO = 0, AUDI, MERCEDES }; 现在,在这个示例应用程序中,用户需要的是他们的汽车制造商的字符串表示形式,而不是数字,因此我使用枚举的字符
class car {
char car_manufacturer;
//other stuff
};
其中,car\u manufacturer
的值为下列值之一:
enum car_manufacturers : char {
VOLVO = 0,
AUDI,
MERCEDES
};
现在,在这个示例应用程序中,用户需要的是他们的汽车制造商的字符串表示形式,而不是数字,因此我使用枚举的字符串表示形式创建了一个数组,其中数组的顺序与枚举相同,因此汽车制造商
可以用作数组索引
std::string car_manufacturers_strings[MERCEDES + 1] = {
"Volvo",
"Audi",
"Mercedes"
};
因此,现在在加载文件并从数据中创建car
对象之后,我可以通过car\u manufacturers\u strings[car.car\u manufacturer]以字符串的形式获得汽车的品牌代码>
这样做的好处是,在文件中,我不必存储大量重复的字符串,如果汽车是同一品牌的,那么我可以节省大量空间。但是这种方法的缺点是代码稍微复杂一些
那么这种做法是好是坏呢?将枚举数的字符串表示形式作为数组提供是非常标准的做法
一点是:
std::string car_manufacturers_strings[MERCEDES + 1] = {
"Volvo",
"Audi",
"Mercedes"
};
将字符串文本存储在二进制文件中,并在动态初始化阶段将这些文本的副本创建为std::string
对象
您可能希望将其更改为:
char const* const car_manufacturers_strings[MERCEDES + 1] = {
"Volvo",
"Audi",
"Mercedes"
};
这样就不会不必要地创建这些副本。将枚举数的字符串表示形式作为数组提供是非常标准的做法
一点是:
std::string car_manufacturers_strings[MERCEDES + 1] = {
"Volvo",
"Audi",
"Mercedes"
};
将字符串文本存储在二进制文件中,并在动态初始化阶段将这些文本的副本创建为std::string
对象
您可能希望将其更改为:
char const* const car_manufacturers_strings[MERCEDES + 1] = {
"Volvo",
"Audi",
"Mercedes"
};
这样就不会不必要地创建这些副本。将枚举数的字符串表示形式作为数组提供是非常标准的做法
一点是:
std::string car_manufacturers_strings[MERCEDES + 1] = {
"Volvo",
"Audi",
"Mercedes"
};
将字符串文本存储在二进制文件中,并在动态初始化阶段将这些文本的副本创建为std::string
对象
您可能希望将其更改为:
char const* const car_manufacturers_strings[MERCEDES + 1] = {
"Volvo",
"Audi",
"Mercedes"
};
这样就不会不必要地创建这些副本。将枚举数的字符串表示形式作为数组提供是非常标准的做法
一点是:
std::string car_manufacturers_strings[MERCEDES + 1] = {
"Volvo",
"Audi",
"Mercedes"
};
将字符串文本存储在二进制文件中,并在动态初始化阶段将这些文本的副本创建为std::string
对象
您可能希望将其更改为:
char const* const car_manufacturers_strings[MERCEDES + 1] = {
"Volvo",
"Audi",
"Mercedes"
};
这样它就不会不必要地创建这些副本。我通常使用一个函数来创建这些副本,大致如下:
char const * to_string(car_manufacturers cm) {
switch (cm) {
#define CASE(CM) case CM: return #CM;
CASE(Volvo)
CASE(Audi)
CASE(Mercedes)
#undef CASE
}
return "Unknown"; // or throw, or whatever
}
优点:
- 无需将参数转换为数字索引,因此它可以处理范围枚举,而无需进行可怕的强制转换李>
- 如果在不更新函数的情况下添加枚举数,我的编译器会发出警告(虽然不如删除重复项好,但至少保持一致性)
缺点:
开关
的效率可能(也可能不会)低于数组查找
- 枚举数的大写必须与字符串匹配,因此您必须放弃对
SHOUTY_CAPS
的崇拜。有人会说这是件好事;它们确实伤了我的眼睛
- 哎哟!宏李>
我通常使用以下功能:
char const * to_string(car_manufacturers cm) {
switch (cm) {
#define CASE(CM) case CM: return #CM;
CASE(Volvo)
CASE(Audi)
CASE(Mercedes)
#undef CASE
}
return "Unknown"; // or throw, or whatever
}
优点:
- 无需将参数转换为数字索引,因此它可以处理范围枚举,而无需进行可怕的强制转换李>
- 如果在不更新函数的情况下添加枚举数,我的编译器会发出警告(虽然不如删除重复项好,但至少保持一致性)
缺点:
开关
的效率可能(也可能不会)低于数组查找
- 枚举数的大写必须与字符串匹配,因此您必须放弃对
SHOUTY_CAPS
的崇拜。有人会说这是件好事;它们确实伤了我的眼睛
- 哎哟!宏李>
我通常使用以下功能:
char const * to_string(car_manufacturers cm) {
switch (cm) {
#define CASE(CM) case CM: return #CM;
CASE(Volvo)
CASE(Audi)
CASE(Mercedes)
#undef CASE
}
return "Unknown"; // or throw, or whatever
}
优点:
- 无需将参数转换为数字索引,因此它可以处理范围枚举,而无需进行可怕的强制转换李>
- 如果在不更新函数的情况下添加枚举数,我的编译器会发出警告(虽然不如删除重复项好,但至少保持一致性)
缺点:
开关
的效率可能(也可能不会)低于数组查找
- 枚举数的大写必须与字符串匹配,因此您必须放弃对
SHOUTY_CAPS
的崇拜。有人会说这是件好事;它们确实伤了我的眼睛
- 哎哟!宏李>
我通常使用以下功能:
char const * to_string(car_manufacturers cm) {
switch (cm) {
#define CASE(CM) case CM: return #CM;
CASE(Volvo)
CASE(Audi)
CASE(Mercedes)
#undef CASE
}
return "Unknown"; // or throw, or whatever
}
优点:
- 无需将参数转换为数字索引,因此它可以处理范围枚举,而无需进行可怕的强制转换李>
- 如果在不更新函数的情况下添加枚举数,我的编译器会发出警告(虽然不如删除重复项好,但至少保持一致性)
缺点:
开关
的效率可能(也可能不会)低于数组查找
- 枚举数的大写必须与字符串匹配,因此您必须放弃对
SHOUTY_CAPS
的崇拜。有人会说这是件好事;它们确实伤了我的眼睛
- 哎哟!宏李>
您可以向类中添加一个方法来实现这一点。然后,这些字符串以与制造商枚举相同的顺序存储在一个数组中,这是一个对用户隐藏的实现细节。@MicroVirus这正是我在应用程序中实现的,cars就是一个类比。事实上,我实现了相当于car.get_car\u manufacturer\u name()
您可以向类中添加一个方法,该方法正好可以做到这一点。那么,事实是