【问题标题】:Problems creating a convenient C++ singleton template创建方便的 C++ 单例模板的问题
【发布时间】:2021-02-05 21:29:20
【问题描述】:

首先,请不要给我讲“单身不好”。我已经阅读了所有相关内容,并查看了我所拥有的用例的替代方案,这是最合适的。

好的,我正在尝试根据我所知道的和读过的内容创建一个方便的 C++ 单例模板。我已经走到这一步了:

template <class T>
class Singleton{
protected:
    Singleton(); // Disallow instantiation outside of the class.
public:
    Singleton(const T&) = delete;
    T& operator=(const T&) = delete;
    Singleton(T &&) = delete;
    T& operator=(T &&) = delete;

    static auto& Instance(){
        static T instance;
        return instance;
    }
};

class Derived : public Singleton<Derived> {
  Derived() {}
  friend class Singleton<Derived>;
};

main() {
  auto derived = Derived::Instance();
}

编译时出现链接器错误:

undefined reference to `Singleton<Derived>::Singleton()'

.. 我不明白为什么。我对模板编程的理解力有限。

我还想避免在派生类和朋友类语句中创建构造函数的需要。我理解为什么需要它,但我宁愿能够使用一些模板魔术来为 Singleton 模板中的 Derived 类创建默认构造函数。我知道构造函数不能被继承,但认为模板魔法至少可以自动创建一个。

我认为我在概念上试图做的事情很清楚,所以如果有一个更简单的整体方法可行,那也很好。目标是不必为我需要定义的每种不同类型的单例编写所有已删除的运算符和实例创建函数。

任何帮助都会被虚心接受(只要不是单例讲座 :-)

【问题讨论】:

  • 一旦你说and this is the best fit,我简直不敢相信你。单身人士很少有这样的情况,他们可以使代码库受益而不是破坏其质量。创建您需要的类,在 main() 的开头对其进行实例化,并将其作为参数传递给所有需要它的函数(我曾经将 context_t 引用作为我编写的所有函数的第一个参数传递)。并发性始终很重要。
  • @Andrew 没有回答问题吗?

标签: c++ c++11 templates singleton


【解决方案1】:

只是一个错字发生了 - 你的构造函数缺少它的实现

class Singleton{
protected:
    Singleton()=default; // You probably meant this.
public:
    //...
};

【讨论】:

    【解决方案2】:

    您已经为Singleton&lt;T&gt; 声明了默认构造函数,但您还没有在任何地方定义它。您可以像这样提供内联定义:

    template <class T>
    class Singleton{
    protected:
        Singleton() { /* definition goes here */ }
    
    public:
    // ...
    };
    

    如果你不需要在构造函数中做任何特别的事情,或者只是默认它:

    template <class T>
    class Singleton{
    protected:
        Singleton() = default;
    
    public:
    // ...
    };
    

    此外,如果您只想将 Derived 构造函数留空,则可以省略它:

    class Derived : public Singleton<Derived> {
      // Derived() {} the compiler will generate this for you
      friend class Singleton<Derived>;
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      • 2011-06-03
      相关资源
      最近更新 更多