隐藏的单例,用于封装初始化和销毁代码

Hidden singleton to encapsulate initialization and destruction code

本文关键字:代码 初始化 封装 单例 用于 隐藏      更新时间:2023-10-16

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

框架.h

namespace framework {
    //void init(); // want this to be automatic.
    //void quit(); 
    float func1();
    void func2(int i);
    //...
}

框架.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);
    }
}

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

这个设计有什么问题吗...

好吧,链接器有可能与在其他地方声明/定义的另一个类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);
    }
}