隐藏单例来封装初始化和销毁​​代码

时间:2017-10-09 21:56:13

标签: c++ singleton c++14

我有一个需要手动初始化和销毁​​的库,我想自动完成该过程。由于init和quit函数都应该只被调用一次我认为一个好的解决方案是使用单例,但由于调用Singleton::instance().func()很烦人地调用每个函数,我在cpp文件中实现了Singleton并使用了标题中的函数作为单例方法的包装器。

Framework.h

namespace framework {
    //void init(); // want this to be automatic.
    //void quit(); 

    float func1();
    void func2(int i);
    //...
}

Framework.cpp

namespace framework
{
    class Framework
    {
    private:
        Framework() {
            //init code
            //...
        }

        ~Framework() {
            //quit code
            //...
        }

    public:
        Framework(const Framework&)            = delete;
        Framework& operator=(const Framework&) = delete;

        static Framework& instance() {
            static Framework result; //on first call initialization code is run.
            return result;
        }

        float func1() {
            //...
        }

        void func2(int i) {
            //...
        }
    };

    // wrapper functions
    float func1() {
         return Framework::instance().func1();
    }

    void func2(int i) {
        Framework::instance().func2(i);
    }
}

除了使用常规单例时可能出现的一般问题外,此设计是否存在任何问题?

1 个答案:

答案 0 :(得分:0)

  

此设计有任何问题......

嗯,链接器可能会与在其他地方声明/定义的另一个类framework::Framework的模糊性发生冲突。

您应该将该单例封装到翻译单元中的匿名/未命名命名空间中:

namespace { // <<<< Guarantees that everything within this is only 
            // visible within this translation unit, even when linking that code.
    class Framework
    {
    private:
        Framework() {
            //init code
            //...
        }

        ~Framework() {
            //quit code
            //...
        }

    public:
        Framework(const Framework&)            = delete;
        Framework& operator=(const Framework&) = delete;

        static Framework& instance() {
            static Framework result; //on first call initialization code is run.
            return result;
        }

        float func1() {
            //...
        }

        void func2(int i) {
            //...
        }
    };
}
namespace framework
{
    // wrapper functions
    float func1() {
         return Framework::instance().func1();
    }

    void func2(int i) {
        Framework::instance().func2(i);
    }
}