c++的vector指针,vector的声明和指针的删除

C++ vector of pointers, vector declaration and deletion of pointers

本文关键字:vector 指针 删除 声明 c++      更新时间:2023-10-16

假设我有一个单例类:

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
  • Delegator类的main()中,我调用getVector()并显示结果。

考虑到这个抽象,我有以下问题:

  1. 我可以从Delegator中删除main()中对象实例的所有指针(显示结果后)。如果是,是否推荐这样做?
  2. 单例被销毁了吗?换句话说,在getVector()中返回的引用总是有效的吗?
  3. 我返回对矢量的引用,而不是getVector()中矢量的副本。考虑到向量只包含指向对象的指针,并且不会修改Singleton类之外的向量内容,返回引用是否有任何效率?

提前感谢

典型的单例模式是这样的(也可能有其他的变化,比如在实例中使用引用而不是指针)

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;
}

在您的例子中,您返回了一个单例实例的副本,这违反了单例模式。

回答你的问题。问:绝不应该删除单例对象。然而,定义析构函数是为了使它成为私有的,否则调用者可以使用delete Singleton::getInstance(),这不是一个好主意。

也就是说,单例在大多数情况下被认为是反模式。在大多数情况下,实用程序类更适合。实用程序类是一个非常相似的概念,但它们实现的一切都是静态的,而不是使用实例。当您需要初始化代码时,请使用init()方法(因为不涉及构造函数)。

对于你没有问的问题,我的第一个回答是:

不要使用Singleton。这是一个反模式。它使它接触的代码变得更糟。它破坏了可测试性,并且使将来修改程序变得更加困难。

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

为了回答你问的问题…

    是的,你可以。当然,这些指针仍然在向量中,所以向量现在包含了大量的悬空指针。所以你也应该清除向量。有了你的代码,它将永远不会被破坏。根据某些定义,这使得您的Singleton存在内存泄漏。所以,是的,引用将始终有效。
  1. 是的,返回一个引用有一个巨大的性能改进。复制vector对象意味着复制vector对象中的所有元素。注意,这意味着所有指针都将被复制,而不是它们所指向的Object。此外,如果你返回一个副本,并让main函数删除所有指针,你绝对保证有一个矢量,里面有一大堆悬空指针。
  1. 这完全取决于你的要求和设计。从这个角度来看,您呈现的代码是中性的。

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

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