使用 CRTP 实现单例

2024-04-01

看完之后这个答案 https://stackoverflow.com/a/4173298/7151494我尝试过实现一些简单的 CRTP 用法。我想我会尝试实现 Singleton(是的,我知道 - 这只是为了练习和研究)模式,因为链接的答案kind of已经做到了...除了它无法编译这一事实。

引用的代码如下:

template <class ActualClass> 
class Singleton
{
   public:
     static ActualClass& GetInstance()
     {
       if(p == nullptr)
         p = new ActualClass;
       return *p; 
     }

   protected:
     static ActualClass* p;
   private:
     Singleton(){}
     Singleton(Singleton const &);
     Singleton& operator = (Singleton const &); 
};
template <class T>
T* Singleton<T>::p = nullptr;

class A: public Singleton<A>
{
    //Rest of functionality for class A
};

然后我将其“现代化”为:

template <class T>
class Singleton {
public:
    Singleton()                              = delete;
    Singleton(const Singleton&)              = delete;
    Singleton(Singleton&&)                   = delete;
    Singleton& operator = (const Singleton&) = delete;
    Singleton& operator = (Singleton&&)      = delete;

    static T& get_instance() {
        if(!instance)
            instance = new T;
        return *instance;
    }

   protected:
     static inline T* instance = nullptr;
};

class A: public Singleton<A> {
    //Rest of functionality for class A
};

然后我尝试创建对该实例的引用:

auto& x = A::get_instance();

显然没有编译。

值得一提的是,我收到了非常相似的错误消息,特别是:

注意:“A::A()”被隐式删除,因为默认定义格式不正确:class A : public Singleton<A>.

显然,第二段代码cannot编译,因为我们删除了默认构造函数并尝试将其与new T in the get_instance method.

令我惊讶的是,第一个代码片段也无法编译,并带有类似的错误消息。链接的答案有错误吗?我将如何实施单例的通用基类/接口使用CRTP?


这是“现代化”片段的修改:

template <class T>
class Singleton {
public:
    Singleton& operator = (const Singleton&) = delete;
    Singleton& operator = (Singleton&&)      = delete;

    static T& get_instance() {
        if(!instance)
            instance = new T_Instance;
        return *instance;
    }

protected:
    Singleton() {}

private:
    struct T_Instance : public T {
        T_Instance() : T() {}
    };

    static inline T* instance = nullptr;
};

class A : public Singleton<A> {
protected:
    A() {}
};

int main()
{
    auto& x = A::get_instance();
}

代码片段的更改摘要:

  • protected单例中的默认构造函数
  • private嵌套结构来访问派生类的受保护构造函数
  • protected派生类中的构造函数以防止实例化

另外,无需delete通过向 Singleton 类添加默认 ctor 实现来隐式删除的构造函数。

不那么小理查德·霍奇斯 https://stackoverflow.com/users/2015579/richard-hodges' 示例,但是静态instancemember 可以轻松添加用于自动化单元测试的 delete_instance() 方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 CRTP 实现单例 的相关文章

随机推荐

  • 覆盖 Rails 中的 MIME 类型

    我想将 Rails 中的 JSON MIME 类型 application json 覆盖为 text x json 我尝试在 mime types rb 中再次注册 MIME 类型 但这不起作用 有什么建议么 Thanks 这应该可以工作
  • c2512 错误:没有合适的默认构造函数可用

    即使我声明了构造函数 我也遇到了 c2512 错误 我的代码是这样的 在我的 first h 文件中 我将其声明为 class myClass public tmpM cv Mat model 然后在我的 first cpp 中我做了 in
  • 从 Word OLE 应用程序对象获取应用程序标题

    有没有办法从 Word Application OLE 对象获取窗口标题 我想用它来尝试使用窗口FindWindow 我正在创建一个 OLE 对象并添加一个现有文档 如下所示 App CreateOLEObject Word Applica
  • Java - 如何限制特定方法的方法调用

    我有一个特殊的要求 我需要确保只允许一个类中的特定方法调用第二个类中的公共 非静态 方法 不能使用继承 一种选择是使用 StackTrace 如下所示 A类 java package org rnd stack public class C
  • .ToTitleCase 不适用于所有大写字符串

    Public Function TitleCase ByVal strIn As String Dim result As String Dim culture As New CultureInfo en False Dim tInfo A
  • 将 std::wstring 从 Visual Studio 移植到 mingw gcc

    我正在将一些代码从 Visual Studio 移植到 mingw gcc 我看到了这个声明 if mnode GetTag T val return true 这是 GetTag 方法的定义 const std wstring GetTa
  • Python 多处理与多线程相结合

    我不确定我想做的是否是有效的做法 但事情是这样的 我需要我的程序高度并行化 所以我想我可以创建 2 3 个进程 每个进程可以有 2 3 个线程 1 这可能吗 2 这有什么意义吗 3 这是我的代码 但当我尝试加入进程时它会挂起 PQ mult
  • 如何在 React-Navigation/Drawer 6 中实现“返回”

    我在 React navigation drawer 6 中实现 goBack 功能时遇到问题 react navigation drawer 6 1 4 准确地说 我能够使用以下代码在react navigation drawer 5中完
  • 解析 JSON 数据以将其显示在 gridview 中

    我创建了一个应用程序 它将数据从 URL 解析为 JSON 对象并将其显示在GridView 虽然没有显示错误 但每次运行应用程序时都会收到消息不幸的是 应用程序已停止运行 这是我的申请文件 MainActivity java packag
  • 将 HttpResponse 转换为 .apk 文件

    问题是这样的 我与某个 url 建立互联网连接并收到带有 app example apk 的 HttpResponse 然后我想创建一个文件 apk 在带有此数据的 SD 卡中 以便此下载的应用程序 可以稍后安装 如何将 HttpRespo
  • 如何在样式表中使用非标准自定义字体?

    我有一个PyQt4由外部设计的应用程序 qss使用以下代码创建文件 app QtGui QApplication sys argv stylesheet open mystylesheet qss read app setStyleShee
  • 使用 pyspark 使用嵌套结构 ArrayType 展平数据框

    我有一个具有此架构的数据框 root AUTHOR ID integer nullable false NAME string nullable true Books array nullable false element struct
  • Project.json 定义 dnx451 与 .dotnet ( 4.51)

    我有一些 在 asp vnext 中我可以定义 3 种类型的运行时 dnxCore dnx451 dotnet 在 Project json 中 它看起来像这样 frameworks dotnet dnx451 dnxcore50 用户界面
  • 如何使用 Java 创建 TensorProto for TensorFlow?

    现在我们使用tensorflow serving进行推理 它公开了 gRPC 服务 我们可以从 proto 文件生成 Java 类 现在我们可以生成PreditionService from https github com tensorf
  • 如何在 Angular 中包含 JavaScript 脚本文件并从该脚本调用函数?

    我有一个名为的 JavaScript 文件abc js有一个名为 公共 的函数xyz 我想在我的 Angular 项目中调用该函数 我怎么做 参考里面的脚本angular cli json angular json当使用 Angular 6
  • 从列表创建虚拟变量

    因此 我尝试根据框架的特定列是否包含特定单词来创建虚拟变量以附加到数据框架 该列看起来像这样 dumcol c good night moon good night room good morning room hello moon 我将根
  • 如何更改 Xcode 中文本字段的键盘类型

    我在 XCode 中创建了一个文本字段 而不是 Interface Builder 在 IB 中您可以选择不同的键盘类型 如何在 XCode 中做同样的事情 怎么样keyboardType http developer apple com
  • Asp.NET Web API 中的控制器和类列表

    我想访问我的 Web api 中的所有控制器 假设我有 2 个控制器和 2 个类 Foo string fooId string fooName Bar string barId string barName 样本1控制器 Get int
  • 同时使用 JSON 和 XML 格式的 WCF ResponseFormat?

    例如 当使用 REST 请求对象时 是否可以获取 json 和 xml 格式的响应 或者我是否必须创建类似以下内容的 UriTemplates WebInvoke UriTemplate format json user id Respon
  • 使用 CRTP 实现单例

    看完之后这个答案 https stackoverflow com a 4173298 7151494我尝试过实现一些简单的 CRTP 用法 我想我会尝试实现 Singleton 是的 我知道 这只是为了练习和研究 模式 因为链接的答案kin