Kai*_*zay 25 c++ static constant-expression
我有字符串常量,我在我的应用程序中的多个位置使用的字符串:
namespace Common{
static const std::string mystring = "IamAwesum";
}
Run Code Online (Sandbox Code Playgroud)
当发布关于其他内容的问题时(编译期间未包含在目标中的.h文件会发生什么?),另一位用户发表了以下评论:
请注意,在这种情况下,您的静态字符串是全局的.所以他们可以在任何时候创建一个例外,并且无法捕获.我建议你使用返回字符串引用的函数.std :: string const&mystring {static std :: string const mystring ="IamAwesum"; 通过这种方式返回mystring}你的对象只在需要时构造
有人可以解释为什么以我上面这样的方式使用静态const字符串,冒着抛出异常的风险吗?
krz*_*zaq 31
N4140§3.6.2[basic.start.init]/4
它是实现定义的,是否在第一个语句之前完成了具有静态存储持续时间的非局部变量的动态初始化
main.
N4140§N414015.3 [except.handle]/13
与静态存储对象的析构函数或与静态存储时间命名空间范围对象的构造函数抛出的异常没有被捕获功能试块上
main().
你根本无法捕获字符串构造函数生成的异常 - 比如说std::bad_alloc.
(意见)话虽如此,对于这么小的字符串,我觉得这种考虑是偏执的.
唯一的“问题”——如果你可以这样称呼它——我在你的代码中看到的是,你通过不必要地将已经恒定的数据复制到动态分配的缓冲区(形式上是恒定的,但实际上不是恒定的)来浪费资源)。这会使用所需物理内存的两倍,并执行不必要的复制。
有关系吗?几乎可以肯定,不会。即使在“内存相当有限”的系统上,无论是从执行时间的角度还是从内存消耗的角度来看,这一点现在都很难被注意到。
至于异常,从技术上来说当然是正确的,std::string必须进行的分配可能会失败,因此构造函数可能会抛出异常,而您将无法捕获它。但请现实一点。
这几乎可以保证不会发生,但即使发生了……如果在程序启动时为几个字符串分配内存这样的小事失败了,那么您就会遇到一个完全不同规模的非常非常严重的问题!
此外,正如上面另一个答案的评论中指出的:假设这种情况确实发生,你打算怎么做?该程序完全无法运行,因此您可以想象杀死该程序。
现在,随着 C++17 的出现并不遥远,并且string_view已经在几个主流编译器中可用std::experimental,您可以尝试另一件事:使用正确的东西。
string_view与 a 相反,Astring不会分配非常量内存,而是将常量数据复制到其中,然后假装它是常量。相反,它将直接管理指向常量数据的指针,仅此而已。
这样,您的常量就真正(不仅仅是形式上)常量,没有分配,不可能出现异常,并且不会使用双倍内存。在大多数情况下,它看起来和闻起来仍然像string. 唯一显着的区别是 astring_view不保证 nul 终止(但它指向的字符常量确实如此,所以这是无关紧要的),而且它确实是常量,不可修改......这正是您想要的。
| 归档时间: |
|
| 查看次数: |
3258 次 |
| 最近记录: |