lb.*_*lb. 429 c++ string static const class
我想为一个类(在这种情况下是一个形状工厂)有一个私有静态常量.
我想要有类似的东西.
class A {
private:
static const string RECTANGLE = "rectangle";
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我从C++(g ++)编译器中得到了各种错误,例如:
ISO C++禁止成员'RECTANGLE'的初始化
非整数类型'std :: string'的静态数据成员的无效类初始化
错误:使'RECTANGLE'静止
这告诉我这种成员设计不符合标准.如何在不使用#define指令的情况下拥有私有文字常量(或者可能是公共的)(我想避免数据全局性的丑陋!)
任何帮助表示赞赏.
AnT*_*AnT 451
您必须在类定义之外定义静态成员并在那里提供初始化程序.
第一
// In a header file (if it is in a header file in your case)
class A {
private:
static const string RECTANGLE;
};
Run Code Online (Sandbox Code Playgroud)
然后
// In one of the implementation files
const string A::RECTANGLE = "rectangle";
Run Code Online (Sandbox Code Playgroud)
您最初尝试使用的语法(类定义中的初始化程序)仅允许使用整数和枚举类型.
从C++ 17开始,您有另一个选项,它与您的原始声明非常相似:内联变量
// In a header file (if it is in a header file in your case)
class A {
private:
inline static const string RECTANGLE = "rectangle";
};
Run Code Online (Sandbox Code Playgroud)
无需额外定义.
aby*_*s.7 147
在C++ 11中,您现在可以做到:
class A {
private:
static constexpr const char* STRING = "some useful string constant";
};
Run Code Online (Sandbox Code Playgroud)
sel*_*tze 33
在类定义中,您只能声明静态成员.它们必须在课堂之外定义.对于编译时积分常量,标准会使您可以"初始化"成员.但它仍然不是一个定义.例如,如果没有定义,那么获取地址是行不通的.
我想提一提,我没有看到使用的std :: string在为const char []的利益为常数.std :: string很好,除了它需要动态初始化.所以,如果你写的东西像
const std::string foo = "hello";
Run Code Online (Sandbox Code Playgroud)
在命名空间范围内,foo的构造函数将在执行main启动之前运行,此构造函数将在堆内存中创建常量"hello"的副本.除非你真的需要RECTANGLE成为std :: string,否则你也可以写
// class definition with incomplete static member could be in a header file
class A {
static const char RECTANGLE[];
};
// this needs to be placed in a single translation unit only
const char A::RECTANGLE[] = "rectangle";
Run Code Online (Sandbox Code Playgroud)
那里!没有堆分配,没有复制,没有动态初始化.
干杯,s.
GMa*_*ckG 17
这只是额外的信息,但如果您真的想要在头文件中使用该字符串,请尝试以下方法:
class foo
{
public:
static const std::string& RECTANGLE(void)
{
static const std::string str = "rectangle";
return str;
}
};
Run Code Online (Sandbox Code Playgroud)
虽然我怀疑这是推荐的.
Oz *_*mon 13
在C++ 17中,您可以使用内联变量:
class A {
private:
static inline const std::string my_string = "some useful string constant";
};
Run Code Online (Sandbox Code Playgroud)
请注意,这与abyss.7的答案不同:这个定义了一个实际的std::string
对象,而不是一个const char*
类静态变量可以在标头中声明,但必须在.cpp文件中定义。这是因为静态变量只能有一个实例,并且编译器无法决定将其放置在哪个生成的目标文件中,因此您必须做出决定。
为了用C ++ 11中的声明保留静态值的定义,可以使用嵌套的静态结构。在这种情况下,静态成员是一个结构,必须在.cpp文件中定义,但值在标头中。
class A
{
private:
static struct _Shapes {
const std::string RECTANGLE {"rectangle"};
const std::string CIRCLE {"circle"};
} shape;
};
Run Code Online (Sandbox Code Playgroud)
无需初始化单个成员,而是在.cpp中初始化整个静态结构:
A::_Shapes A::shape;
Run Code Online (Sandbox Code Playgroud)
通过以下方式访问值
A::shape.RECTANGLE;
Run Code Online (Sandbox Code Playgroud)
或-由于成员是私有成员,并且只能从A使用-
shape.RECTANGLE;
Run Code Online (Sandbox Code Playgroud)
注意,该解决方案仍然遭受静态变量的初始化顺序的问题。当使用静态值初始化另一个静态变量时,第一个静态变量可能尚未初始化。
// file.h
class File {
public:
static struct _Extensions {
const std::string h{ ".h" };
const std::string hpp{ ".hpp" };
const std::string c{ ".c" };
const std::string cpp{ ".cpp" };
} extension;
};
// file.cpp
File::_Extensions File::extension;
// module.cpp
static std::set<std::string> headers{ File::extension.h, File::extension.hpp };
Run Code Online (Sandbox Code Playgroud)
在这种情况下,静态变量头将包含{“”}或{“ .h”,“ .hpp”},具体取决于链接程序创建的初始化顺序。
如@ abyss.7所述,constexpr
如果可以在编译时计算变量的值,则也可以使用。但是,如果使用声明字符串,static constexpr const char*
并且程序使用std::string
否则,则会产生开销,因为std::string
每次使用该常量时都会创建一个新对象:
class A {
public:
static constexpr const char* STRING = "some value";
};
void foo(const std::string& bar);
int main() {
foo(A::STRING); // a new std::string is constructed and destroyed.
}
Run Code Online (Sandbox Code Playgroud)
小智 5
快进到 2018 年和 C++17。
static_assert 仅在编译时“有效”
using namespace std::literals;
namespace STANDARD {
constexpr
inline
auto
compiletime_static_string_view_constant() {
// make and return string view literal
// will stay the same for the whole application lifetime
// will exhibit standard and expected interface
// will be usable at both
// runtime and compile time
// by value semantics implemented for you
auto when_needed_ = "compile time"sv;
return when_needed_ ;
}
Run Code Online (Sandbox Code Playgroud)
};
以上是一个正当的、合法的标准C++公民。它可以轻松参与任何和所有 std:: 算法、容器、实用程序等。例如:
// test the resilience
auto return_by_val = []() {
auto return_by_val = []() {
auto return_by_val = []() {
auto return_by_val = []() {
return STANDARD::compiletime_static_string_view_constant();
};
return return_by_val();
};
return return_by_val();
};
return return_by_val();
};
// actually a run time
_ASSERTE(return_by_val() == "compile time");
// compile time
static_assert(
STANDARD::compiletime_static_string_view_constant()
== "compile time"
);
Run Code Online (Sandbox Code Playgroud)
享受标准 C++
归档时间: |
|
查看次数: |
353130 次 |
最近记录: |