相关疑难解决方法(0)

Nifty/Schwarz计数器,符合标准?

我今天早上和一位同事就静态变量初始化顺序进行了讨论.他提到了Nifty/Schwarz计数器,我(有点)感到困惑.我理解它是如何工作的,但我不确定这在技术上是否符合标准.

假设以下3个文件(前两个是来自更多C++习语的 copy-pasta ):


//Stream.hpp
class StreamInitializer;

class Stream {
   friend class StreamInitializer;
 public:
   Stream () {
   // Constructor must be called before use.
   }
};
static class StreamInitializer {
  public:
    StreamInitializer ();
    ~StreamInitializer ();
} initializer; //Note object here in the header.
Run Code Online (Sandbox Code Playgroud)
//Stream.cpp
static int nifty_counter = 0; 
// The counter is initialized at load-time i.e.,
// before any of the static objects are initialized.
StreamInitializer::StreamInitializer ()
{
  if (0 == nifty_counter++)
  {
    // Initialize Stream …
Run Code Online (Sandbox Code Playgroud)

c++ static-order-fiasco

16
推荐指数
1
解决办法
2228
查看次数

为什么这些函数本地静态对象的破坏顺序与其初始化顺序不相反?

我有两个函数本地静态对象,一个和两个.一个人的构造函数和析构函数都通过GetTwo()访问两个:

#include <iostream>

struct One;
struct Two;

const One& GetOne();
const Two& GetTwo();

struct Two {
  const char* value = "It's two!";
  Two() { std::cout << "Two construct" << std::endl; }
  ~Two() { std::cout << "Two destruct" << std::endl; }
};

struct One {
  One() {
    std::cout << "One construct" << std::endl;
    const char* twoval = GetTwo().value;
    std::cout << "twoval is: " << twoval << std::endl;
  }
  ~One() {
    std::cout << "One destruct" << std::endl;
    const char* twoval = GetTwo().value; …
Run Code Online (Sandbox Code Playgroud)

c++ static-initialization c++11

6
推荐指数
2
解决办法
504
查看次数

静态数据成员是否真的可以进行延迟初始化?

是否可以在真正需要时初始化Singleton的实例?

考虑从着名的"设计模式"中获取的这种模式:

class Singleton {
public:
   static Singleton* Instance();
protected:
   Singleton();
private:
   static Singleton* _instance;
}

Singleton* Singleton::_instance = 0; // unit.cpp

static Singleton* Singleton::Instance() {
   if (_instance == 0) {
       _instance = new Singleton;
   }
   return _instance;
}
Run Code Online (Sandbox Code Playgroud)

现在,我认为那里的模式存在问题,如果有人希望将库中的Singleton提供给其他人:如果用户Singleton::Instance()在初始化_instance之前从另一个编译单元调用(例如在静态数据成员初始化期间),然后跟随调用Singleton::Instance()可能会创建Singleton的另一个实例,并产生不需要的结果,因为_instance可能首先被初始化为0.

我认为一种解决方案是以这种方式初始化_instance:

Singleton* Singleton::_instance = Singleton::Instance();
Run Code Online (Sandbox Code Playgroud)

无论如何,这使得初始化对于那些不需要调用Singleton :: Instance()来初始化其静态数据的人来说不是"懒惰".

是否有更好的解决方案,以便在需要Singleton实例时可以进行初始化?

c++ lazy-loading

3
推荐指数
1
解决办法
5116
查看次数

现代C++中的全局变量

创建一个所有成员(属性,函数)都是静态的类的(目标)缺点是什么?特别是与命名空间的使用相比?或者您更愿意创建全局变量/函数?

我喜欢创建静态属性,因为我发现它们"更整洁".(我确切地知道它们来自哪里等等)我对命名空间不是很熟悉.而且我不舒服,在所有的全局变量,因为我不是很熟悉C语言的关键字,例如extern和static.

此外,如果我们考虑班级

class MyStaticClass
{
    private:

        static int x;
        static double y;

    public:

        static float s;
        static double weatherForecast(unsigned int, char);
};
Run Code Online (Sandbox Code Playgroud)

和命名空间

namespace MyNamespace
{
    int x;
    double y;
    float s;
    double weatherForecast(unsigned int, char);
}
Run Code Online (Sandbox Code Playgroud)
  1. 在通话MyStaticClass::weatherForecast和通话之间是否存在差异(性能方面)MyNamespace::weatherForecast?

  2. 阅读/写作MyStaticClass::s和阅读/写作之间是否存在差异(表现方面)MyNamespace::s?

  3. 如果使用类而不是主要类型,上述问题的任何答案都会改变吗?

c++ static global

2
推荐指数
1
解决办法
879
查看次数