【问题标题】:Defining class string constants in C++?在 C++ 中定义类字符串常量?
【发布时间】:2009-01-20 02:23:23
【问题描述】:

我见过这两种风格的代码,我不确定是否比另一种更好(这只是风格问题)?你有什么建议为什么你会选择一个而不是另一个。

 //Example1
 class Test {

    private:
        static const char* const str;

};

const char* const Test::str = "mystr";

//Example2
class Test {

     private:
         static const std::string str;

};

const std::string Test::str ="mystr";

【问题讨论】:

    标签: c++


    【解决方案1】:

    通常你应该更喜欢std::string 而不是普通的字符指针。然而,在这里,用字符串字面量初始化的 char 指针有一个显着的好处。

    静态数据有两种初始化方式。一种叫静态初始化,一种叫动态初始化。对于那些使用常量表达式初始化并且是 POD(如指针)的对象,C++ 要求它们的初始化在一开始就发生,在动态初始化发生之前。初始化这样的 std::string 将动态完成。

    如果您有一个类的对象是某个文件中的静态对象,并且需要在其初始化期间访问字符串,您可以依赖它在使用 const char* const 版本时已经设置好,在使用未静态初始化的std::string 版本时,您不知道字符串是否已经初始化 - 因为未定义跨翻译单元边界的对象初始化顺序。

    【讨论】:

    • +1 我花了一些时间调试一些非常讨厌的崩溃,这些崩溃是由字符串类的静态实例引起的,这些实例由于初始化顺序问题而中断。避免 std::string 的静态实例!
    • 我对这个答案感到非常惊讶。有什么方法可以使它与 std::string 一起工作?
    • @test: 是的:std::string const& safe_string_const() { std::string static const var = "const"; return var; }
    • @AndyT 你应该把static 放在类型之前。它是一个存储类说明符(例如extern 或(对于成员)mutable),不是 cv-qualifier (@987654329 @ 和 volatile)。所以int static i = 0; 确实会编译但是例如int* static p = 0; 不会。 (好的,int static* p 会,但请写static int* p。非常感谢。)
    【解决方案2】:

    嗯,std::string 与 const char * 不同。我通常在使用 std::string 方面犯错,因为它是一个具有许多附加功能的类,使其更易于使用。

    如果性能是最重要的,并且您使用 const char * 来提高效率,那就这样吧。

    【讨论】:

      【解决方案3】:

      在做 C++ 时,我倾向于使用 std::string 而不是 char *。我更喜欢 std::string 主要是因为它的内置功能以及不必处理指针的便利性和安全性。

      但是,正如其他人所提到的,如果您过度关注性能,则 const char * 版本可能会更有利。我似乎记得曾经有一个聪明人说过,过早的优化是万恶之源(或类似的根源)。 :)

      【讨论】:

        【解决方案4】:

        第一个示例需要较少的管理字符串的开销(即,只是指向 TEXT 部分的指针)。此外,第二种方法可能还需要堆分配,以将字符串文字复制到 std:string 类缓冲区。因此,您最终会得到两个数据副本。

        【讨论】:

          【解决方案5】:

          在涉及具有不同编译器和库的多个平台、许多团队和许多人的大型项目中,我们反复遇到静态 std::strings 的问题。在某些平台上,std:string 实现不是线程安全的。在一个平台上,编译器优化的代码跳过了从全局静态常量初始化本地 std:string。在解决了其中一些问题之后,我们只允许内置类型使用全局静态常量。

          【讨论】:

            【解决方案6】:

            第二个版本的优点是它带有预先计算的长度以及充实的字符串类的其他好处。第一个的优点是唯一的初始化只是分配一个指向已经加载到可执行映像中的静态数据的指针,而第二个必须从同一个指针初始化字符串。

            【讨论】:

            • 是的,但这是一个 O(n) 操作,因此根据使用情况,这可能是个问题。
            • 但我想这只是关于 std::string 与 char * 的一般好处的争论。
            【解决方案7】:

            首先,如果不使用 char*。如果你想要一个 ASCIIZ 字符串,直接定义其中一个:

            const char Test::str[] = "mystr";

            在大多数情况下,这就是我会使用的。为什么要为字符串类的开销浪费时间和内存。

            注意“sizeof(Test::str)”会准确地给你数组的长度,也就是字符串的长度,包括终止的NUL(strlen(str)+1)。

            【讨论】:

            • 谁在抄袭?是“const int x = 5;”复制什么?只有一个 char[] 本质上持有值“mystr”;
            猜你喜欢
            • 2022-12-12
            • 2012-03-27
            • 2011-11-26
            • 1970-01-01
            • 1970-01-01
            • 2010-11-01
            • 1970-01-01
            • 2012-01-03
            • 1970-01-01
            相关资源
            最近更新 更多