代码之家  ›  专栏  ›  技术社区  ›  void.pointer

静态变量:使用后进行构造

c++
  •  0
  • void.pointer  · 技术社区  · 10 年前

    我正在一个控制台应用程序中使用Visual Studio 2013进行一些测试。涉及静态变量,我看到一些奇怪的行为。主要问题是静态 Printer 成员 GenericFactory 构造模板类 之后 我用它(在它里面) Register 函数)!

    关于全局/静态变量和初始化顺序的规则非常复杂,所以有人可以帮助我理解这里的问题吗?代码如下。

    main.cpp:

    #include <iostream>
    
    int main()
    {
       std::cout << "Main Function\n";
    }
    

    通用系数.hpp:

    #pragma once
    
    #include <functional>
    #include <map>
    #include <memory>
    #include <iostream>
    
    class Printer
    {
    public:
       Printer()
       {
          std::cout << "Printer class created\n";
       }
    
       void Stuff()
       {
          std::cout << "Printer Stuff, Address " << (int)this << "\n";
       }
    };
    
    template<typename Key>
    class GenericFactory
    {
    public:
    
       static Key const& Register(Key const& key)
       {
          GenericFactory::s_printer.Stuff();
          std::cout << "Registered: " << key << "\n";
          return key;
       }
    
    private:
       static Printer s_printer;
    };
    
    template<typename Key>
    Printer GenericFactory<Key>::s_printer;
    

    字符串系数.hpp:

    #pragma once
    
    #include <string>
    #include "GenericFactory.hpp"
    
    using StringFactory = GenericFactory<int>;
    

    测试1.cpp:

    #include "StringFactory.hpp"
    
    namespace Other
    {
       static auto key = StringFactory::Register(100);
    }
    

    测试2.cpp:

    #include "StringFactory.hpp"
    
    namespace Other
    {
       static auto key = StringFactory::Register(200);
    }
    

    运行上述应用程序后得到的输出:

    Printer Stuff, Address 3422532
    Registered: 100
    Printer class created
    Printer Stuff, Address 3422532
    Registered: 200
    Main Function
    

    请注意 "Printer Stuff, ..." 之前已打印 "Printer class created" .我在这里疯了吗?

    1 回复  |  直到 10 年前
        1
  •  3
  •   Photon    10 年前

    假设全局变量的构造顺序。这不是一个好方法。 尝试将其更改为以下内容(不是最干净的,但很重要):

    template<typename Key>
    class GenericFactory
    {
       static Printer& printer()
       {
           static Printer s_printer;
           return s_Printer;
       }
    public:
    
    
       Key const& Register(Key const& key) // removed static here.
       {
          printer().Stuff();
          std::cout << "Registered: " << key << "\n";
          return key;
       }
    
    };
    

    编辑:

    下面是我用于不需要多线程双重锁保护的单线程的典型模式:

    #include <memory>
    
    class MySingletonClass
    {
    public:
      static MySingletonClass* instance()
      {
        static std::unique_ptr<MySingletonClass> ptr(new MySingletonClass);
        return ptr.get();
      }
    
      // Public functions here
    
    private:
      friend struct std::default_delete<MySingletonClass>;
      // Hide these to avoid unintentional copy
      MySingletonClass() {}
      ~MySingletonClass() {}
      MySingletonClass(const MySingletonClass&) {}
      MySingletonClass& operator= (const MySingletonClass&) { return *this; }
    };
    

    如果您也想增加线程安全性,可以通过搜索找到许多文章: https://www.google.com/search?q=singleton+c%2B%2B+double+checked+locking