我们假设我有一个单身人士课程:
class Singleton {
public:
static Singleton* getInstance();
void doit();
std::vector<Object*>& getVector();
private:
std::vector<Object*> _vector;
static Singleton *instance;
Singleton();
~Singleton();
Singleton(const Singleton&);
};
class Delegator {
public:
void main();
}
doit
方法中,我使用指向对象的指针填充_vector
。main()
课程的Delegator
中,我致电getVector()
并显示结果。鉴于这种抽象,我有以下问题:
main()
中删除Delegator
中所有对象实例的指针(显示结果后)。如果是的话,这是推荐的吗? getVector()
中返回的引用是否始终有效? getVector()
中返回对向量的引用,而不是向量的副本。假设向量只包含指向对象的指针而不会修改Singleton
类之外的向量内容,那么返回引用是否有效率? 提前谢谢
答案 0 :(得分:4)
典型的单例模式看起来像这样(其他变体是可能的,比如使用引用而不是实例的指针)。
singleton.h:
class Singleton {
public:
static Singleton* getInstance();
...
private:
static Singleton *instance;
Singleton(); //permit construction of instances
~Singleton(); //permit deletion of instances
Singleton(const Singleton&); //don't provide an implementation for copy-ctr.
};
singleton.cpp:
Singleton *Singleton::instance = 0;
Singleton::Singleton() {
// init your stuff
}
Singleton::~Singleton() {
}
Singleton *Singleton::getInstance() {
if(!instance) instance = new Singleton();
return instance;
}
在您的情况下,您将返回违反单例模式的单例实例的副本。
回答你的2.问题:永远不应删除单身人士。但是,我们定义了一个析构函数,因此我们可以将其设为私有,否则调用者可以delete Singleton::getInstance()
这不是一个好主意。
话虽如此,单身人士在大多数情况下被视为反模式。在大多数情况下,实用程序类更适合。实用程序类是一个非常相似的概念,但它们实现静态而不是使用实例。当您需要初始化代码时,请使用init()
方法执行此操作(因为不涉及构造函数)。
答案 1 :(得分:2)
这完全取决于您的要求和设计。从这个角度来看,您呈现的代码是中立的。
同样,这取决于您的设计和实施。 singleton pattern
本身并不意味着终生。如果您需要singleton
在某个生命周期内有效,您需要通过其他方式确保(例如,定义它的全局实例)。
是的,有性能提升。 vector
的实例不是简单的array
,除了实际存储的信息之外还包含大量数据。如果按值返回,将复制所有数据(将此讨论的优化放在一边)。另外,正如在另一个答案中正确指出的那样,按值返回实际上会破坏singleton pattern
。
答案 2 :(得分:2)
我对你没有提出的问题的第一个答案是:
不要使用Singleton 。这是一种反模式。它使代码更糟糕。它会破坏可测试性并使将来修改程序变得更加困难。
这篇非常优秀的文章详细讲述了why Singleton is a bad idea。
回答你提出的问题......
Object
。另外,如果你返回一个副本并让main
函数删除所有指针,你绝对可以保证有一个向量,其中有大量的悬空指针。