类中的静态字符串常量与常量的命名空间 [c++]

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3670031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:26:29  来源:igfitidea点击:

static string constants in class vs namespace for constants [c++]

c++namespacesconstantsstring-constant

提问by Asif Mohammed

I want to declare string constants that will be used across variousclasses in the project. I am considering two alternatives

我想声明将在项目中的各个类中使用的字符串常量。我正在考虑两种选择

Option 1:

选项1:

#header file 
class constants{
    static const string const1;
};

#cpp file

const string constants::const1="blah";

Option 2:

选项 2:

#header file 
namespace constants{
    static const string const1="blah";
};

Just wondering what would be a better implementation.

只是想知道什么是更好的实现。

Already looked at

已经看过

Where to store Class Specific named constants in C++

Where to put constant strings in C++: static class members or anonymous namespaces

在 C++ 中存储特定于类的命名常量的位置

在 C++ 中放置常量字符串的位置:静态类成员或匿名命名空间



UPDATE:

更新:

Option 3:

选项 3:

Based on the suggestions from "potatoswatter" and "sellibitze" i currently have the following implementation?

根据“potatoswatter”和“sellibitze”的建议,我目前有以下实现?

#header file
namespace constants{
    extern const string& const1(); //WORKS WITHOUT THE EXTERN  ***WHY***
};

#cpp file
namespace constants{
   const string& const1(){static string* str = new string ("blah"); return *str;}
}

I'm including the header file where i need to use the constants. Are there any major cons of this implementation?

我在需要使用常量的地方包含了头文件。这种实现有什么主要缺点吗?

采纳答案by Potatoswatter

Update 2 years later:

两年后更新:

Every global accessible by more than one source file should be wrapped in an inlinefunction so the linker shares the object between the files, and the program initializes it properly.

每个可被多个源文件访问的全局inline变量都应包含在一个函数中,以便链接器在文件之间共享对象,并且程序会正确初始化它。

inline std::string const &const1() {
    static std::string ret = "hello, world!";
    return ret;
}

The inlinefunction is implicitly externand may be wrapped in a named namespace or a class, if you like. (But don't use a class just to hold static members, as namespaces are better for that. And don't use an anonymous namespace as that would defeat the linker, and each source would see a different std::stringobject.)

inline函数是隐式的extern,如果您愿意,可以将其包装在命名空间或类中。(但不要只使用类来保存静态成员,因为命名空间对此更好。不要使用匿名命名空间,因为这会破坏链接器,并且每个源都会看到不同的std::string对象。)

回答by legends2k

All answers that resort to std::stringrun the risk of dynamically allocating memory for a string literal which is going to remain constant throughout the lifetime of the program (and the binary), so they should be avoided.

所有答案都会std::string冒着为字符串文字动态分配内存的风险,该字符串文字将在程序(和二进制文件)的整个生命周期中保持不变,因此应该避免使用它们。

sellibitze's answer comes close but it has the problem of declaring it once and then defining it elsewhere, which I don't find elegant and is more work. The best way would be

sellibitze的答案很接近,但它有一个问题,即声明一次然后在其他地方定义它,我觉得这并不优雅,而且工作量更大。最好的方法是

namespace constants {
    const char * const blah = "blah!"
    const char * const yada = "yada yada!"
}

This is solution is discussed further here.

此处将进一步讨论此解决方案。

回答by sellibitze

Neither. I'd go with this:

两者都不。我会这样做:

// header file
namespace constants {
extern const char const1[];
}

// cpp file
namespace constants {
extern const char const1[] = "blah";
}

The header file contains a declaration of const1with incomplete type but convertible to char const*and the cpp-file contains a definition of the character array with external linkage. There is no dynamic initialization like you have with std::string. So, that's a plus, IMHO.

头文件包含const1类型不完整但可转换为的声明,char const*cpp 文件包含具有外部链接的字符数组的定义。没有像std::string. 所以,恕我直言,这是一个加分项。

回答by The Communist Duck

Option 1 achieves the same as Option 2, but in a messier way.

选项 1 的效果与选项 2 相同,但方式更混乱。

If you're going to use a class that just has static members, especially for global access/constants, use a namespace.

如果您要使用只有静态成员的类,尤其是对于全局访问/常量,请使用命名空间。