【问题标题】:Possible to make a singleton struct in C++? How?可以在 C++ 中创建单例结构吗?如何?
【发布时间】:2013-03-03 15:36:43
【问题描述】:

随着我对编码的了解越来越多,我喜欢进行试验。我有一个程序在它的运行时只需要一个结构的单个实例,并且想知道是否可以创建一个单例结构。我在互联网上看到了很多关于制作单例类的信息,但没有看到关于制作单例结构的信息。这可以做到吗?如果有,怎么做?

提前致谢。哦,顺便说一句,我使用 C++ 工作。

【问题讨论】:

  • 请记住,在 C++ 中,classstruct 是相同的。唯一的区别是struct 默认成员为public
  • 这是否意味着您可以将方法放入结构中? (如果它们是“相同的”)。而且,如果是这样,那么我可以在结构中执行运算符重载之类的操作吗?
  • 请注意,在 C++11 之前,静态初始化不是线程安全的,因此如果您从多个线程调用 singleton::get_instance(),您需要一个互斥锁来防止竞争条件。
  • @JoachimPileborg 和继承默认为 public

标签: c++ struct singleton


【解决方案1】:

classstruct 几乎相同,除了一些次要细节(例如其成员的默认访问级别)。因此,例如:

struct singleton
{
    static singleton& get_instance()
    {
        static singleton instance;
        return instance;
    }

    // The copy constructor is deleted, to prevent client code from creating new
    // instances of this class by copying the instance returned by get_instance()
    singleton(singleton const&) = delete;

    // The move constructor is deleted, to prevent client code from moving from
    // the object returned by get_instance(), which could result in other clients
    // retrieving a reference to an object with unspecified state.
    singleton(singleton&&) = delete;

private:

    // Default-constructor is private, to prevent client code from creating new
    // instances of this class. The only instance shall be retrieved through the
    // get_instance() function.
    singleton() { }

};

int main()
{
    singleton& s = singleton::get_instance();
}

【讨论】:

  • @Spook:正确。我忘了添加 static 关键字。我只是在心里这样做。已编辑,谢谢。
  • 您没有隐藏 copy-ctor 和 = 运算符。可以通过复制现有的单例实例来创建一个实例。实际上,您必须像 singleton 是一个类那样实现单例。
  • @Spook:实际上,我猜赋值运算符不需要保护,但移动构造函数需要保护。我会再次编辑
  • 我实际上更喜欢delete 复制构造和分配。我看不出保留私有版本有什么用,但我还没有真正考虑过。
  • 现在你对删除太兴奋了 :-D 除了singleton() { } = delete; 的语法错误之外,你至少需要一个 ctor 才能构造对象。
【解决方案2】:

结构和类在 C++ 中几乎相同(唯一的区别是成员的默认可见性)。

注意,如果你想做一个单例,你必须阻止结构/类用户实例化,所以隐藏ctor和copy-ctor是不可避免的。

struct Singleton
{
private:
    static Singleton * instance;

    Singleton()
    {
    }

    Singleton(const Singleton & source)
    {
        // Disabling copy-ctor
    }

    Singleton(Singleton && source)
    {
        // Disabling move-ctor
    }

public:
    Singleton * GetInstance()
    {
        if (instance == nullptr)
            instance = new Singleton();

        return instance;
    }
}

【讨论】:

  • 我不知道您可以将方法放在这样的结构中。谢谢。我对此表示赞同,因为一个简单的代码示例是我真正想要的东西之一(不是唯一的事情,而是非常重要的事情)。
  • 原来这是 Java,而不是 C++。稍加调整就可以让它工作 - 只是它不会像显示的那样用 g++ 编译。
【解决方案3】:

从概念上讲,structclass 在 C++ 中是相同的,因此创建单例 struct 与创建单例 class 相同。

classstruct 之间的唯一区别是默认访问说明符和基类继承:private 用于 classpublic 用于 struct。例如,

class Foo : public Bar 
{ 
 public: 
  int a;
};

一样
struct Foo : Bar
{
 int a;
};

因此,在单例方面没有根本区别。请务必阅读why singletons are considered bad

这是一个简单的实现:

struct singleton
{
  static singleton& instance()
  {
    static singleton instance_;
    return instance_;
  }
  singleton(const singleton&)=delete;            // no copy
  singleton& operator=(const singleton&)=delete; // no assignment

 private:
  singleton() { .... } // constructor(s)
};

【讨论】:

    【解决方案4】:

    首先,structclass 仅指成员的默认访问权限。你可以用一个结构来做任何你可以用一个类来做的事情。现在,如果您指的是 POD 结构,事情会变得更加复杂。您无法定义自定义构造函数,因此无法仅强制创建单个对象。但是,没有什么能阻止您只实例化一次。

    【讨论】:

    • 谢谢。非常简洁和全面。读到这里,我就明白了。
    • 现在,等一下,这是否意味着我不能在我的单例结构设计中包含属性?这就是重点。程序中结构的一个实例仅用作数据的临时转换位置(具有4个字段的记录)。以下是我的结构代码,但希望向其“添加”代码,使其成为单例: struct Record { //记录 - 临时 - 重用 - 单例?诠释部门编号;字符名称[MAXNAME];诠释年龄;诠释EmplID; // 关键字段 };
    【解决方案5】:

    classstruct 在 C++ 中几乎是同义词。对于单例用例,它们是完整的同义词。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-15
      • 1970-01-01
      相关资源
      最近更新 更多