c ++:初始化静态字符串成员 [英] c++: initializing static string members

查看:115
本文介绍了c ++:初始化静态字符串成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在c ++中初始化静态字符串成员时遇到一些问题。我有几个类,每个都持有代表一个id的几个静态字符串成员。当我通过调用静态函数初始化变量一切都很好。但是,当我想给另一个变量赋值时,它仍然包含空字符串。此代码有什么问题?

  std :: string A :: id()
{
std :: stringstream sst;
sst<< id<<一世;
i ++;
return sst.str();
}

std :: string B :: str = A :: id(); // printsid0;
std :: string C :: str =str; // prints str


std :: string D :: str = B :: str; // prints< - 这里有什么问题?
std :: string D :: str2 = C :: str; // prints

看起来就像我所指的变量C :: str)havent尚未初始化。但是我假设当D :: str = B :: str被执行时C :: str在最后被初始化,因此D :: str也应该包含字符串id0。

解决方案

这是 静态初始化Fiasco



根据C ++标准,具有静态存储持续时间的对象的初始化顺序是未指定的,如果它们在不同的 翻译单位



因此,依赖这些对象的初始化顺序的任何代码都必然失败,这个问题被称为 Static Initialization Fiasco 在C ++中。



您的代码依赖于初始化 B :: str C: :str 发生在 D :: str 之前,这是标准不保证的。由于这3个静态存储持续时间对象位于不同的翻译单元,因此可以按任何顺序进行初始化。



如何避免?



解决方案是使用首次使用成语构建,简而言之就是使用全局函数,通过引用返回对象。引用返回的对象应该是 local static ,因为静态局部对象是在第一次控制流过它们的声明时构造的,所以只有在第一次调用和每次后续调用同一个对象






这应该是一个有趣的读物:



我如何防止静态初始化顺序fiasco?





I'm having some problems initializing static string members in c++. I have several classes and each one is holding several static string members that represent an id. When I am initializing the variables by calling a static function everything is fine. However, when I'd like to assign one variable with the value of another it still holds empty string. What's problem with this code?

std::string A::id()
{
    std::stringstream sst; 
    sst << "id" << i;           
    i++;
    return sst.str();
}

  std::string B::str = A::id(); //prints "id0";
  std::string C::str = "str"; //prints str


  std::string D::str = B::str; //prints "" <-- what's wrong here?
  std::string D::str2 = C::str; //prints ""

It appears as if the variables I am referring to (B::str and C::str) havent been initialized yet. But I assume when D::str = B::str is executed C::str is initialized at the latest and therefore D::str should also hold the string "id0".

解决方案

This is Static Initialization Fiasco.

As per the C++ Standard the initialization order of objects with static storage duration is unspecified if they are declared in different Translation units.

Hence any code that relies on the order of initialization of such objects is bound to fail, and this problem is famously known as The Static Initialization Fiasco in C++.

Your code relies on the condition that Initialization of B::str and C::str happens before D::str, which is not guaranteed by the Standard. Since these 3 static storage duration objects reside in different translation units they might be initialized in Any order.

How to avoid it?

The solution is to use Construct On First Use Idiom,in short it means replacing the global object, with a global function, that returns the object by reference. The object returned by reference should be local static, Since static local objects are constructed the first time control flows over their declaration, the object will be created only on the first call and on every subsequent call the same object will be returned, thus simulating the behavior you need.


This should be an Interesting read:

How do I prevent the "static initialization order fiasco"?


这篇关于c ++:初始化静态字符串成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆