指针的C ++向量,向量声明和指针的删除

时间:2013-01-02 14:26:39

标签: c++ pointers memory-management memory-leaks singleton

我们假设我有一个单身人士课程:

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()中删除Delegator中所有对象实例的指针(显示结果后)。如果是的话,这是推荐的吗?
  2. 单身人物是否会被摧毁?换句话说,getVector()中返回的引用是否始终有效?
  3. 我在getVector()中返回对向量的引用,而不是向量的副本。假设向量只包含指向对象的指针而不会修改Singleton类之外的向量内容,那么返回引用是否有效率?
  4. 提前谢谢

3 个答案:

答案 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)

  1. 这完全取决于您的要求和设计。从这个角度来看,您呈现的代码是中立的。

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

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

答案 2 :(得分:2)

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

不要使用Singleton 。这是一种反模式。它使代码更糟糕。它会破坏可测试性并使将来修改程序变得更加困难。

这篇非常优秀的文章详细讲述了why Singleton is a bad idea

回答你提出的问题......

  1. 是的,你可以。当然,那些指针仍然在向量中,因此向量现在将包含大量悬空指针。所以你也应该清除矢量。
  2. 使用您拥有的代码永远不会被销毁。通过一些定义会使您的Singleton出现内存泄漏。所以,是的,参考将始终有效。
  3. 是的,返回引用有很大的性能提升。复制矢量意味着复制矢量中的所有元素。请注意,这意味着将复制所有指针,而不是它们指向的Object。另外,如果你返回一个副本并让main函数删除所有指针,你绝对可以保证有一个向量,其中有大量的悬空指针。