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()
您可以向类中添加一个方法,该方法正好可以做到这一点。那么,事实是