10

最近,我广泛使用以下 getInstance() 方法阅读了一些 C++ 代码:

class S
{
    private:
        int some_int = 0;
    public:
        static S& getInstance()
        {
            static S instance; / (*) /
            return instance;
        }
};

从这个代码片段的使用方式,我了解到 getInstance() 的工作方式类似于return this,返回 的实例的地址(或引用)class S。但我很困惑。

S1) line(*) 中定义的静态变量在内存中分配在哪里?为什么它可以像这样工作return this

2) 如果存在多个 的实例class S,将返回谁的引用?

4

2 回答 2

8

这就是所谓的Singleton设计模式。它的显着特点是该类只能有一个实例,并且该模式确保了这一点。该类有一个私有构造函数和一个随getInstance方法返回的静态创建的实例。您不能从外部创建实例,因此只能通过所述方法获取对象。

由于instance在方法staticgetInstance,它将在多次调用之间保留其值。它在第一次使用之前被分配和构造。例如,在这个答案中,GCC 似乎在首次使用函数时初始化了静态变量。这个答案有一些与此相关的 C++ 标准的摘录。

于 2013-09-25T05:57:26.883 回答
2

第一次调用函数时分配具有函数范围的静态变量。编译器会跟踪第一次初始化的事实,并避免在下次访问函数时进一步创建。这个属性是实现单例模式的理想选择,因为这样可以确保我们只维护一个对象的副本。此外,较新的编译器确保此分配也是线程安全的,从而在不使用任何动态内存分配的情况下提供额外的线程安全单例实现。[正如评论中所指出的,它是保证线程安全的 c++11 标准,所以如果您使用不同的编译器,请检查线程安全]

1) line(*) 中定义的静态变量 S 在内存中分配在哪里?为什么它可以像返回这个一样工作?

内存中有存储静态变量的特定区域,例如用于动态分配变量的堆和用于典型编译时定义变量的堆栈。它可能因编译器而异,但对于 GCC,在编译器生成的可执行文件中有称为 DATA 和 BSS 段的特定部分,其中存储了已初始化和未初始化的静态变量。

2) 如果存在多个类 S 的实例,将返回谁的引用?

如顶部所述,由于它是一个静态变量,编译器确保在第一次访问函数时只能创建一个实例。此外,由于它在函数中具有范围,因此它不能与存在的任何其他实例发生冲突 else where 和 getInstance 确保您看到相同的单个实例。

于 2013-09-25T06:03:28.327 回答