每个人都知道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)
因为:
static Singleton* operator->() { return instance; }
是不可能的,类成员访问运算符(->)的重载不能是静态的(请参见C2801),与(2)和运算符()相同这里仅提供解决方案:宏,但是我实际上正在使用宏,因此我想找到另一种方法并避免使用宏...
这只是语法上的询问,我不是在这里讨论单例的优缺点,但是我想知道为什么C ++允许这么多事情来简化带有重载,用户文字的用户类的使用语法,而我们可以做到这一点?消除模式中的这个小功能。
我不希望有一个解决方案(但是如果有解决方案,那将是个好主意),只是为了了解原因,知道是否有解释,设计原因,安全原因或其他任何原因!>
谢谢!
答案 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
的成员。