C++类的全局实例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/297822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:24:54  来源:igfitidea点击:

Global instance of a class in C++

c++singleton

提问by Alex Gaynor

As the title says. How would I create an instance of a class that is globally available(for example I have a functor for printing and i want to have a single global instance of this(though the possibility of creating more)).

正如标题所说。我将如何创建一个全局可用的类的实例(例如,我有一个用于打印的函子,我想要一个这样的全局实例(尽管有可能创建更多))。

回答by Greg Hewgill

Going to all the effort of making a singleton object using the usual pattern isn't addressing the second part of your question - the ability to make more if needed. The singleton "pattern" is very restrictive and isn't anything more than a global variable by another name.

使用通常的模式来制作单例对象的所有努力并没有解决问题的第二部分 - 如果需要,能够制作更多。单例“模式”是非常严格的,只不过是另一个名称的全局变量。

// myclass.h

class MyClass {
public:
    MyClass();
    void foo();
    // ...
};

extern MyClass g_MyClassInstance;

// myclass.cpp

MyClass g_MyClassInstance;

MyClass::MyClass()
{
    // ...
}

Now, in any other module just include myclass.hand use g_MyClassInstanceas usual. If you need to make more, there is a constructor ready for you to call.

现在,在任何其他模块中,只需像往常一样包含myclass.h和使用g_MyClassInstance。如果您需要制作更多,有一个构造函数可供您调用。

回答by Martin York

First off the fact that you want global variables is a 'code smell' (as Per Martin Fowler).

首先,您想要全局变量是一种“代码味道”(如 Per Martin Fowler)。

But to achieve the affect you want you can use a variation of the Singleton.
Use static function variables. This means that variable is not created until used (this gives you lazy evaluation) and all the variables will be destroyed in the reverse order of creation (so this guarantees the destructor will be used).

但是要达到您想要的效果,您可以使用 Singleton 的变体。
使用静态函数变量。这意味着变量在使用之前不会被创建(这会给你懒惰的评估)并且所有的变量都将以创建的相反顺序被销毁(因此这保证了析构函数将被使用)。

class MyVar
{
    public:
        static MyVar& getGlobal1()
        {
            static MyVar  global1;
            return global1;
        }
        static MyVar& getGlobal2()
        {
            static MyVar  global2;
            return global2;
        }
        // .. etc
}

回答by Mike Kale

As a slight modification to the singleton pattern, if you do want to also allow for the possibility of creating more instances with different lifetimes, just make the ctors, dtor, and operator= public. That way you get the single global instance via GetInstance, but you can also declare other variables on the heap or the stack of the same type.

作为对单例模式的轻微修改,如果您还想允许创建更多具有不同生命周期的实例的可能性,只需将 ctors、dtor 和 operator= public。这样您就可以通过 GetInstance 获得单个全局实例,但您也可以在堆或堆栈上声明相同类型的其他变量。

The basic idea is the singleton pattern, however.

然而,基本思想是单例模式。

回答by deft_code

I prefer to allow a singleton but not enforce it so in never hide the constructors and destructors. That had already been said just giving my support.

我更喜欢允许单例但不强制它,所以永远不要隐藏构造函数和析构函数。这已经说过只是给予我的支持。

My twist is that I don't use often use a static member function unless I want to create a true singleton and hide the constr. My usual approach is this:

我的扭曲是我不经常使用静态成员函数,除非我想创建一个真正的单例并隐藏 constr。我通常的做法是这样的:

template< typename T >
T& singleton( void )
{
   static char buffer[sizeof(T)];
   static T* single = new(buffer)T;
   return *single;
}

Foo& instance = singleton<Foo>();

Why not use a static instance of T instead of a placement new? The static instance gives the construction order guarantees, but not destruction order. Most objects are destroyed in reverse order of construction, but static and global variables. If you use the static instance version you'll eventually get mysterious/intermittent segfaults etc after the end of main.

为什么不使用 T 的静态实例而不是放置新的?静态实例提供构造顺序保证,但不提供销毁顺序。大多数对象以与构造相反的顺序销毁,但静态和全局变量。如果您使用静态实例版本,您最终会在 main 结束后得到神秘/间歇性段错误等。

This means the the singletons destructor will never be called. However, the process in coming down anyway and the resources will be reclaimed. That's kinda tough one to get used to but trust me there is not a better cross platform solution at the moment. Luckily, C++0x has a made changes to guarantee destruction order that will fix this problem. Once your compiler supports the new standard just upgrade the singleton function to use a static instance.

这意味着永远不会调用单例析构函数。但是,无论如何,在下来的过程中,资源将被回收。这有点难以习惯,但相信我,目前没有更好的跨平台解决方案。幸运的是,C++0x 进行了更改以保证销毁顺序可以解决这个问题。一旦您的编译器支持新标准,只需升级单例函数即可使用静态实例。

Also, I in the actual implemenation I use boost to get aligned memory instead of a plain character array, but didn't want complicate the example

此外,我在实际实现中使用 boost 来获得对齐的内存而不是普通字符数组,但不想使示例复杂化

回答by Joel Martinez

the Singleton patternis what you're looking for.

Singleton模式是你在找什么。

回答by Cyber Oliveira

The simplest and concurrency safe implementation is Scott Meyer's singleton:

最简单且并发安全的实现是 Scott Meyer 的单例:


#include <iostream>

class MySingleton {
public:
    static MySingleton& Instance() {
        static MySingleton singleton;
        return singleton;
    }
    void HelloWorld() { std::cout << "Hello World!\n"; }
};

int main() {
    MySingleton::Instance().HelloWorld();
}

See topic IV herefor an analysis from John Vlissides (from GoF fame).

请参阅此处的主题 IV 了解 John Vlissides(来自 GoF 名气)的分析。

回答by Swapnil

Singleton is nice pattern to use but it has its own disadvantages. Do read following blogs by Mi?ko Hevery before using singletons.

Singleton 是一种很好的使用模式,但它有其自身的缺点。在使用单身人士之前,请阅读 Mi?ko Hevery 的以下博客。

  1. Singletons are Pathological Liars

  2. Root Cause of Singletons

  3. Where Have All the Singletons Gone?

  1. 单身人士是病态的骗子

  2. 单身的根本原因

  3. 所有的单身人士都去哪儿了?