我想使用引用编写Meyers Singleton类,但是它不起作用。尽管打印显示构造函数仅被调用一次,但每次调用实例访问器方法时,我似乎仍会得到该类的单独实例。但是,如果我使用指针编写它,则效果很好。谁能解释为什么以及如何修复参考版本?谢谢!
适用的指针版本:
X.h
class X {
public:
static X *getX(void);
void ipp();
int geti();
private:
X();
int i;
};
X.cpp
#include "X.h"
X::X()
{
printf ("X constructor\n");
i = 0;
}
X *X::getX()
{
static X the_only_X;
return &the_only_X;
}
int X::geti()
{
return (i);
}
void X::ipp()
{
i++;
}
tryit.cpp
#include <stdio.h>
#include "X.h"
int main (int ac, char *av[])
{
printf ("main\n");
X *x1 = X::getX();
x1->ipp();
printf ("i= %d\n", x1->geti());
X *x2 = X::getX(); // same X instance?
x2->ipp();
printf ("i= %d\n", x1->geti());
x1->ipp();
printf ("i= %d\n", x1->geti());
x2->ipp();
printf ("i= %d\n", x1->geti());
return (0);
}
构建并运行,应该得到i = 1、2、3、4:
g++ -Wall X.cpp tryit.cpp && ./a.out
main
X constructor
i= 1
i= 2
i= 3
i= 4
无法使用的参考版本:
X.h:
class X {
public:
static X& getX(void);
void ipp();
int geti();
private:
X();
int i;
};
X.cpp:
#include "X.h"
X::X()
{
printf ("X constructor\n");
i = 0;
}
X& X::getX()
{
static X the_only_X;
return the_only_X;
}
int X::geti()
{
return (i);
}
void X::ipp()
{
i++;
}
tryit.cpp:
#include <stdio.h>
#include "X.h"
int main (int ac, char *av[])
{
printf ("main\n");
X x1 = X::getX();
x1.ipp();
printf ("i= %d\n", x1.geti());
X x2 = X::getX(); // same X instance?
x2.ipp();
printf ("i= %d\n", x1.geti());
x1.ipp();
printf ("i= %d\n", x1.geti());
x2.ipp();
printf ("i= %d\n", x1.geti());
return (0);
}
构建并运行,应该得到i = 1、2、3、4:
ecd-imac27$ g++ -Wall X.cpp tryit.cpp && ./a.out
main
X constructor
i= 1
i= 1
i= 2
i= 2
X x1 = X::getX();
正在复制单例实例。 X x2 = X::getX();
也是。这意味着您实际上有[[0]个实例X
。哎呀。怎么会这样这应该是single吨!如果单例类是可复制和/或可移动的,则它实际上不是单例。因此,可以通过从类中删除复制和移动操作(默认情况下由编译器提供)来表达这一点:
X(const X&) = delete; // Copy ctor
X(X&&) = delete; // Move ctor
X& operator=(const X&) = delete; // Copy assignment
X& operator=(X&&) = delete; // Move assignment
完成此操作后,您会发现X x1 = X::getX();
和X x1 = X::getX();
无法编译。好!编译器阻止您创建更多的X
实例。通过使用引用来解决此问题:
X& x1 = X::getX();
X& x2 = X::getX();
并且所有工作正常:
main
X constructor
i= 1
i= 2
i= 3
i= 4