Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+;中,在哪里放置常量字符串+;:静态类成员还是匿名名称空间?_C++_String_Static_Namespaces_Anonymous - Fatal编程技术网

C++ 在C+;中,在哪里放置常量字符串+;:静态类成员还是匿名名称空间?

C++ 在C+;中,在哪里放置常量字符串+;:静态类成员还是匿名名称空间?,c++,string,static,namespaces,anonymous,C++,String,Static,Namespaces,Anonymous,我需要定义一些仅由一个类使用的常量字符串。看起来我有三个选择: 将字符串直接嵌入到使用它们的位置 将它们定义为类的私有静态常量成员: //A.h class A { private: static const std::string f1; static const std::string f2; static const std::string f3; }; //A.cpp const std::string f1 = "filename1"

我需要定义一些仅由一个类使用的常量字符串。看起来我有三个选择:

  • 将字符串直接嵌入到使用它们的位置

  • 将它们定义为类的私有静态常量成员:

    //A.h  
    class A {  
    private:  
       static const std::string f1;  
       static const std::string f2;  
       static const std::string f3;  
    };  
    
    //A.cpp  
    const std::string f1 = "filename1";  
    const std::string f2 = "filename2";  
    const std::string f3 = "filename3";  
    
    //strings are used in this file  
    
  • 在cpp文件的匿名命名空间中定义它们:

    //A.cpp  
    namespace {  
      const std::string f1 = "filename1";  
      const std::string f2 = "filename2";  
      const std::string f3 = "filename3";  
    }  
    
    //strings are used in this file  
    

  • 考虑到这些选项,您会推荐哪一个?为什么?谢谢。

    如果字符串是要让类的用户看到的,请将它们放入类中。否则,将它们隐藏在实现文件的未命名命名空间中

    如果它们仅在单个文件中使用,则无需通过将它们包含在头文件中而将它们公开给外部世界

    如果它们被使用并且总是只在一个地方使用,那么就没有理由不在需要使用它们的地方将它们作为文本来编写

    如果它们在cpp中的多个位置使用,我会选择匿名名称空间


    您没有提到的另一个选项是将它们定义为cpp中的静态变量。这相当于匿名命名空间选项,并且比C++更类似于C。

    类的静态成员。
    如果一个类在多个地方使用它们,那么如果在使用它们的类中定义它们,通常会更容易保持事物的条理化,并在以后找到定义所有内容的位置。在适当的位置定义它们会使它们很难定位,以后也很难修改。我会选择特定的类而不是匿名名称空间来定义和使用更干净的类。

    在这三个选项中,唯一应该避免的是#1。不要在代码中使用魔法cookies。通过将常量放在名称空间或类中,将来可以更容易地扩展和维护代码

    如果你的常数本质上是全局的,那么在2到3之间,它就无关紧要了。重要的是你选择一个并坚持下去。但是如果您有应用于特定类的常量,那么它们应该是该类的一部分


    就个人而言,我会对大多数事情使用名称空间。

    我会将它们放在CPP文件的匿名名称空间中。它使它们对实现是私有的,同时使它对作为实现一部分的非成员函数可见(例如
    operator),我认为真正的问题是:字符串真的只在实现类时在内部使用,还是在其他地方使用


    为了避免吹毛求疵,我会尽量保持类的接口尽可能干净,因此如果“外部”世界对文件名字符串不感兴趣,我只会将它们隐藏在.cpp文件的内部。在这种情况下,我想我不会对名称空间感到烦恼,只会保持“静态”(即.cpp文件的内部)。

    如果只在类的.cpp文件中使用,则无需使用任何类型的命名空间,只需说:

    const std::string f1 = "filename1";  
    const std::string f2 = "filename2";  
    const std::string f3 = "filename3";  
    

    过度使用名称空间似乎是一件新鲜事——我个人看不出它的吸引力。

    不管你怎么做,有一件事要小心:我不建议使用静态std::string对象,而是使用静态char*。这是由于初始化顺序的潜在问题。假设你有一个类的静态实例其构造函数引用字符串
    A::f1
    。无法保证
    A::f1
    已被构造,您将得到崩溃,或者更糟的是,没有崩溃,只有虚假数据


    跟踪初始化错误的顺序可能会非常棘手,一个项目中的一切看起来都很好,但随后您可能会使用相同的库构建另一个项目,链接顺序中的细微差异将导致此错误神秘地出现。

    只需在实现文件中的文件范围内设置常量字符串,即可匿名名称空间不必限制它们仅用于该类

    C.1.2第3条:基本概念

    Change: A name of file scope that is explicitly declared const, and not explicitly declared extern, has internal linkage, while in C it would have external linkage
    

    注意:匿名名称空间确实有助于减少命名冲突。

    感谢您的提醒。我也倾向于使用此选项。这些字符串最希望是常量。但如果以后我决定更改其中一个文件名,我可以轻松地在那里执行此操作,而无需担心重新编译包含头文件的所有内容。值得注意的是hat,即使您将它们定义为类内的静态常量,实际文本仍必须在实现文件中。因此,更改文件名不需要重新编译任何内容,只需要重新编译一个文件。没错,Dennis。添加/删除这些常量时,这只会在编译方面产生影响。修改它们应该是同样。关于原始问题,匿名命名空间是不必要的,因为默认情况下,在文件作用域中声明的常量具有内部链接。如果您不担心名称冲突,则只需删除匿名命名空间。但是,如果在其他编译单元中存在名称f1、f2等,则可能会导致链接器错误。这就是why匿名名称空间存在。这些定义和匿名名称空间之间有什么区别吗?在我看来,它们被隐式定义为“静态”@维迪奇不,它不会。在名称空间范围内声明的const对象是翻译单元的本地。@尼尔。你是对的。在C++中,常量值默认为内部链接。@尼尔:匿名命名空间和答案之间的区别是什么?不使用命名空间。如果调用使用SITE的函数,那么注意到这是危险的。在main启动之前,从其他翻译单元中删除字符串:函数可能会在创建字符串对象之前访问这些对象。因此,我将去掉常量std::string对象,并使用
    char const f1[]=“filename”
    用于此。@litb:似乎您是说使用原语类型char比t中的字符串对象更安全