单例 C++ 模板类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11452760/
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 15:09:14  来源:igfitidea点击:

Singleton C++ template class

c++templatessingleton

提问by Patryk

Possible Duplicate:
Why can templates only be implemented in the header file?

可能的重复:
为什么模板只能在头文件中实现?

I realise that there are already few topics like this on SO but I did not find any that would answer my problem.

我意识到在 SO 上已经很少有这样的主题了,但我没有找到任何可以回答我的问题的主题。

I have already written my template singleton class using this tutorial http://www.codeproject.com/Articles/4750/Singleton-Pattern-A-review-and-analysis-of-existin

我已经使用本教程编写了我的模板单例类http://www.codeproject.com/Articles/4750/Singleton-Pattern-A-review-and-analysis-of-existin

but unfortunately I keep on getting errors :

但不幸的是我不断收到错误:

/home/USER/testcode/cpp_workshop/main.cpp:-1: error: undefined reference to `Singleton::Instance()' :-1: error: collect2: ld

/home/USER/testcode/cpp_workshop/main.cpp:-1: 错误: 未定义对`Singleton::Instance()'的引用:-1: 错误: collect2: ld

my singleton.h

我的单身.h

#ifndef SINGLETON_H
#define SINGLETON_H

template <typename T>
class Singleton
{
public:
    static T& Instance();

protected:
    virtual ~Singleton();
    inline explicit Singleton();

private:
    static T* _instance;
    static T* CreateInstance();
};

template<typename T>
T* Singleton<T>::_instance = 0;

#endif // SINGLETON_H

singleton.cpp

单例.cpp

#include "singleton.h"
#include <cstdlib>

template <typename T>
Singleton<T>::Singleton()
{
    assert(Singleton::_instance == 0);
    Singleton::_instance = static_cast<T*>(this);
}

template<typename T>
 T& Singleton<T>::Instance()
{
    if (Singleton::_instance == 0)
    {
        Singleton::_instance = CreateInstance();
    }
    return *(Singleton::_instance);
}

template<typename T>
inline T* Singleton<T>::CreateInstance()
{
    return new T();
}

template<typename T>
Singleton<T>::~Singleton()
{
    if(Singleton::_instance != 0)
    {
        delete Singleton::_instance;
    }
    Singleton::_instance = 0;
}

and that's how I call it (with normall - not templated or anything - class Game) Singleton<Game>::Instance().run();

这就是我所说的(正常 - 不是模板化或任何东西 - 类GameSingleton<Game>::Instance().run();

回答by David

Put your method definitions under your class definition in the header, and delete your cpp. Templated methods and methods of templated classes must be defined in headers (with a couple hackish exceptions).

将您的方法定义放在标题中的类定义下,然后删除您的 cpp。模板化方法和模板化类的方法必须在头文件中定义(有几个hackish 例外)。

Per request, here are the 'hackish exceptions':

根据请求,以下是“骇人听闻的例外”:

  • 1) See @Desmond Hume's answer
  • 2) Only use the templated class from the cpp in which the methods are defined. For example, you can declare/define a templated class in an unnamed namespace in a cpp, that's just fine.
  • 1) 见@Desmond Hume 的回答
  • 2) 仅使用定义方法的 cpp 中的模板化类。例如,您可以在 cpp 的未命名命名空间中声明/定义模板化类,这很好。

回答by Desmond Hume

You could put the definition of your Singletonclass into the header file oryou could keep the separation of declarations (the header) and definitions (the .cpp file) as it is now if you like it better and explicitly instantiatethe Singletonclass with each of the types you are going to use it with. To explicitly instantiate Singletonclass, try putting the following at the end of the .cpp file:

你可以把你的定义Singleton类成头文件或者你可以继续申报(头)和定义(.cpp文件)的分离,因为它是现在,如果你喜欢它更好,显式实例Singleton与每类您将要使用它的类型。要显式实例化Singleton类,请尝试将以下内容放在 .cpp 文件的末尾:

template
class Singleton<Game>;

With another type it would look in the same way:

对于另一种类型,它的外观相同:

template
class Singleton<AnotherGame>; // just for example

回答by Moataz Elmasry

Its not possible to separate the definiton (header file) and implementation (cpp) of a templated class. So you have one of two solutions:

无法将模板化类的定义(头文件)和实现(cpp)分开。所以你有两个解决方案之一:

1- implement everything in the header file .h. something like this

1- 在头文件 .h 中实现所有内容。像这样的东西

template <typename T>
class Singleton
{
public:
    static T& Instance(){}

protected:
    virtual ~Singleton(){}
    inline explicit Singleton(){}

private:
    static T* _instance;
    static T* CreateInstance(){}
};

Another solution is to rename your .cpp class to .hpp. Don't include the .h file inside the .hpp file, but the other way around. i.e. include .hpp file inside .h file

另一种解决方案是将您的 .cpp 类重命名为 .hpp。不要在 .hpp 文件中包含 .h 文件,反之亦然。即在 .h 文件中包含 .hpp 文件

I personally prefer the first solution

我个人更喜欢第一个解决方案

Cheers

干杯