Singleton:避免GetIntance()

时间:2018-11-11 00:48:38

标签: c++ singleton

每个人都知道singleton pattern(非常简单的例子):

class Singleton
{
private:
    static Singleton* instance;

public:
    static Singleton* GetInstance() { return instance; }

    void Foo() {}
};

和用途:

Singleton::GetInstance()->Foo();

我想知道为什么这个GetInstance()是强制性的。我试图找到一种方法来消除对此函数的调用,以便能够举例说明...:

Singleton->Foo();

...由于使用单例模式,因此使用类名的方式与使用变量的方式相同,并且还具有其他安全性,例如删除公共构造函数,例如,我们确定我们只有一个实例,所以为什么不使用“将类用作变量”(引用,取消引用,当然只是语法上的解释!)。

每次,C ++规则都禁止以下示例:

Singleton->Foo(); // (1)
Singleton()->Foo(); // (2)
Singleton.Foo(); // (3)
Singleton::Foo(); // (4)

因为:

  • (1)static Singleton* operator->() { return instance; }是不可能的,类成员访问运算符(->)的重载不能是静态的(请参见C2801),与(2)和运算符()相同
  • (3)和(4)运算符。和::不能重载

这里仅提供解决方案:宏,但是我实际上正在使用宏,因此我想找到另一种方法并避免使用宏...

这只是语法上的询问,我不是在这里讨论单例的优缺点,但是我想知道为什么C ++允许这么多事情来简化带有重载,用户文字的用户类的使用语法,而我们可以做到这一点?消除模式中的这个小功能。

我不希望有一个解决方案(但是如果有解决方案,那将是个好主意),只是为了了解原因,知道是否有解释,设计原因,安全原因或其他任何原因!

谢谢!

2 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是将问题的单例部分简化为仅数据,并创建可通过“实例”函数(在此示例中称为self())访问数据的静态函数:

class Singletonish
{
private:
    // single (inaccessible) instance of the data
    static auto& self()
    {
        static struct {
            std::string s = "unset";
            int i = 0;
        } data;
        return data;
    }

public:

    static void foo()
    {
        // foo code here
        self().s = "hello";
        self().i = 9;
    }

    static void woo()
    {
        // woo code here
        std::cout << self().s << '\n';
        std::cout << self().i << '\n';
    }
};

int main()
{
    Singletonish::woo();

    Singletonish::foo();

    Singletonish::woo();
}

输出:

unset
0
hello
9

我个人建议以常规方式进行操作:https://stackoverflow.com/a/1008289/3807729

答案 1 :(得分:0)

我可以在env = simpy.Environment() env.process(env1(env)) env.run(until=500) 中想到以下方式:

C++11

现在,使用此代码,您只需创建#include <memory> struct singleton { int i; }; template <class Singleton_t> struct singleton_holder { auto* operator -> () const noexcept { static Singleton_t s; return std::addressof(s); } }; // optional C++14 feature, can be commented if wanted template <class Singleton_t> constexpr const static /* inline */ singleton_holder<Singleton_t> singleton_v{}; 并使用singleton_holder<singleton> s直接访问s->i的成员即可。

或者您可以使用singleton的方式:C++14直接访问singleton_v<singleton>->i的成员。