def*_*ode 16 c++ inline constants c++11
我想要一个带有非整数常量的头文件,例如一个类.注意常数也并不需要是一个编译时间常数.
static const std::string Ten = "10";
Run Code Online (Sandbox Code Playgroud)
这编译但不可取,因为每个编译单元现在都有自己的Ten副本.
const std::string Ten = "10";
Run Code Online (Sandbox Code Playgroud)
这将编译但会因为多重定义的Ten的链接器错误而失败.
constexpr std::string Ten = "10"s;
Run Code Online (Sandbox Code Playgroud)
这可以工作,但前提是字符串构造函数也是constexpr.它会但是我不能指望每个非整数常量都有一个constexpr构造函数......或者我可以吗?
extern const std::string Ten = "10";
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但我担心如果我错误地呼吸,我会收到链接器错误.
inline const std::string Ten( ) { return "10"; }
Run Code Online (Sandbox Code Playgroud)
这有我想要的一切,除了干净的语法.另外,现在我必须将常量称为函数调用Ten().
inline const std::string = "10";
Run Code Online (Sandbox Code Playgroud)
这似乎是理想的解决方案.当然inline,标准不允许变量.
AnT*_*AnT 27
你好像混淆了他们.
你是对的
static const std::string Ten = "10";
Run Code Online (Sandbox Code Playgroud)
版.它将"工作",但它将在每个翻译单元中创建一个单独的对象.
没有版本static将具有相同的效果.它不会产生链接器错误,但会在每个转换单元中定义一个单独的对象.在C++中,语言const对象默认具有内部链接,这意味着
const std::string Ten = "10"; // `static` is optional
Run Code Online (Sandbox Code Playgroud)
与之前的版本完全相同static.
带extern和初始化程序的版本
extern const std::string Ten = "10"; // it's a definition!
Run Code Online (Sandbox Code Playgroud)
会产生一个定义具有外部链接一个对象的(它是一个定义,因为一个初始化的存在).此版本将导致链接器错误,因为您将最终得到具有外部链接的对象的多个定义 - 违反ODR.
为了实现您想要实现的目标,您必须在头文件中声明您的常量
extern const std::string Ten; // non-defining declaration
Run Code Online (Sandbox Code Playgroud)
然后在一个且只有一个实现文件中定义它(使用初始化程序)
extern const std::string Ten = "10"; // definition, `extern` optional
Run Code Online (Sandbox Code Playgroud)
(如果常量被预先声明为extern,那么extern在定义中是可选的.即使没有显式,extern它也会定义一个带有外部链接的const对象.)
pax*_*blo 10
我不知道C++中是否有更好的方法,但C中最好的方法(也适用于C++)是你列出的方法之一.
有一个单独的编译单元(例如ten.cpp),只保存数据:
const std::string Ten = "10";
Run Code Online (Sandbox Code Playgroud)
和一个头文件(例如ten.h)声明它,以便它可以在别处使用:
extern const std::string Ten;
Run Code Online (Sandbox Code Playgroud)
然后你必须确保任何想要使用它的编译单元包括头文件(例如ten.h),并且任何想要使用它的可执行文件链接到单独的编译单元(例如ten.o).
这为您提供了变量的一个副本,可在任何地方访问.当然,您可以在头文件中将其定义为静态,并为每个编译单元创建一个副本.这将简化您需要的文件,静态将确保没有双重定义的符号.但这不是我推荐过的.
我不知道你为什么说:
但是,如果我错误地呼吸,我恐怕会收到链接器错误
这是很久以前的公认实践,如果你想称自己为C++程序员(没有任何侮辱),你应该知道所有这些东西是如何组合在一起的.
该extern版本是接近你想要什么.这里:
// in the file tenconstant.cpp
const std::string Ten = "10";
// in the file tenconstant.h
extern const std::string Ten;
// in your file
#include "tenconstant.h"
// do stuff with Ten
Run Code Online (Sandbox Code Playgroud)
你需要为链接器定义一次,这是目的myconstants.cpp,但是在你使用它的任何地方声明,这是目的myconstants.h.对于一个变量来说,这看起来有点笨拙,但是对于一个更大的项目,你可能会有一个很好的标题,你可以使用它很多.