0

假设我有一个单例类:

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()并显示结果。

鉴于这种抽象,我有以下问题:

  1. main()我可以删除from中的所有指向 Object 实例的指针Delegator(显示结果后)。如果是,是否建议这样做?
  2. 单身人士会被摧毁吗?换句话说,返回的引用是否getVector()总是有效的?
  3. 我返回对向量的引用,而不是在getVector(). 鉴于向量只包含指向对象的指针,不会修改Singleton类外的向量内容,返回引用是否有效率?

先感谢您

4

3 回答 3

4

典型的单例模式看起来像这样(其他变体也是可能的,例如使用引用而不是实例的指针)。

单例.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.
};

单例.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()方法执行此操作(因为不涉及构造函数)。

于 2013-01-02T14:38:54.760 回答
2

我对你没有问的问题的第一个答案是:

不要使用单例。这是一种反模式。它使它接触到的代码变得更糟。它会扼杀可测试性,并使将来修改程序变得更加困难。

这篇非常棒的文章非常详细地讨论了为什么 Singleton 是一个坏主意

要回答您提出的问题...

  1. 是的你可以。当然,这些指针仍将在向量中,因此向量现在将包含大量悬空指针。所以你也应该清除向量。
  2. 使用您拥有的代码,它将永远不会被破坏。通过一些定义,使您的 Singleton 成为内存泄漏。所以是的,参考将始终有效。
  3. 是的,返回引用有巨大的性能改进。复制向量意味着复制向量中的所有元素。请注意,这意味着将复制所有指针,而不是Object它们指向的 s。此外,如果您返回一个副本并让main函数删除所有指针,那么您绝对可以保证有一个向量在其中,其中包含大量悬空指针。
于 2013-01-02T15:09:48.543 回答
2
  1. 这完全取决于您的要求和设计。从这个角度来看,您提供的代码是中立的。

  2. 同样,这取决于您的设计和实施。singleton pattern本身并不意味着寿命。如果您需要在singleton某个生命周期内有效,则需要通过其他方式确保它(例如,定义它的全局实例)。

  3. 是的,有性能提升。实例vector并不简单array,除了实际存储的信息外,还包含大量数据。如果按值返回,所有数据都将被复制(抛开本次讨论的优化)。此外,正如另一个答案中正确指出的那样,按值返回实际上破坏了singleton pattern.

于 2013-01-02T14:49:16.900 回答