【问题标题】:How does getInstance() work?getInstance() 是如何工作的?
【发布时间】:2013-09-25 05:54:30
【问题描述】:

最近我阅读了一些 C++ 代码,大量使用了 getInstance() 方法:

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

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

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

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

【问题讨论】:

    标签: c++ oop static


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢。很有帮助。 private 构造函数和 static 实例 virable 的组合是关键。
    【解决方案2】:

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

    1) line(*) 中定义的静态变量 S 在哪里分配 记忆?为什么它可以像 return this 一样工作?

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

    2) 如果存在多个类 S 的实例怎么办? 引用将被返回?

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

    【讨论】:

    • 您对线程安全部分是错误的(或至少是误导性的),不是新的编译器使它成为线程安全的,而是 C++11 标准(显然只有更新的编译器版本支持那个)。一个在 C++03 模式下编译的最新编译器仍然允许编译这个非线程安全的。
    猜你喜欢
    • 2010-09-23
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 2016-11-13
    • 2017-10-11
    • 2021-10-13
    • 2011-02-24
    相关资源
    最近更新 更多