【问题标题】:C++ singleton and new operatorC++ 单例和新运算符
【发布时间】:2016-12-12 07:14:54
【问题描述】:

嗨,我有一个 sn-p 代码,它是一个单例类(我相信),它以我以前从未见过的方式使用“新”和其他一些范围和静态限定符。因为我不知道它叫什么,所以我找不到任何关于它的作用或用途的信息。代码如下:

在我的 myClass.h 文件中

class myClass
{
private:
    static myClass sm_myClass;
    myClass();
public:
    static void Create(void);
};

在 myClass.cpp 我有

#include "myClass.h"
#include <new>

myClass* p_myClass = NULL;

myClass myClass::sm_myClass;

myClass::myClass()
{
}

void myClass::Create(void)
{
    p_myClass = &sm_myClass;

    new (p_myClass) myClass();
}

我的问题是:

1 - .cpp 文件的第 6 行 (myClass myClass::sm_myClass;) 发生了什么

2 - .cpp 文件的第 16 行 (new (p_myClass) myClass(); ) 发生了什么

3 - 以这种方式使用类的总体目的是什么?

我真的希望这个问题不要重复。我搜索了一段时间的答案,但不知道要搜索什么术语。感谢您的帮助。

【问题讨论】:

  • FWIW 如果你想使用单例,请参阅:stackoverflow.com/questions/1008019/c-singleton-design-pattern
  • 您可能还想阅读What is so bad about singletons?
  • 对象sm_myClass在程序启动时被构造。对placement new 的调用尝试在已经存在的对象之上构造一个新对象,从而给出未定义的行为。
  • @PeteBecker:在现有对象上放置新位置实际上是可以的,但显然不建议这样做。 IIRC,如果你依赖析构函数来获得一些副作用,它只是 UB。
  • @GManNickG -- 在有限的情况下可能没问题,但这是高级技术,完全不适合初学者的代码。

标签: c++ class scope singleton


【解决方案1】:

1) 静态成员变量需要在一个编译单元 (.cpp/.cxx) 中分配存储空间。这个定义确立了这一点。

2) 这称为placement new,它允许您将对象构造到已分配的内存中。这种用法是有缺陷的,因为该对象已经被构造并且该构造正在被覆盖。

3) 有时将全局服务封装到一个对象中很方便,而单例为该服务的客户提供访问它的简便方法。

【讨论】:

  • 在这里完全不使用展示位置新,没有理由这样做。
【解决方案2】:

1 - .cpp 文件的第 6 行 (myClass myClass::sm_myClass;) 发生了什么

定义了一个静态类成员。

2 - .cpp 文件的第 16 行 ( new (p_myClass) myClass(); ) 发生了什么

一个placement new被指定重用分配给p_myClass的内存

3 - 以这种方式使用类的总体目的是什么?

在某些情况下 singletons 可能会派上用场,但通常最好传递接口,而不是将客户端代码紧密耦合到 myClass


不要使用new(是否放置new)来初始化单例实例。请改用 Scott Meyer 的 单例实现,这可以保证线程安全:

class myClass
{
private:
    myClass();
public:
    static myClass& instance() {
         static myClass theInstance;
         return theInstance;
    }
};

实例将在第一次访问instance() 函数时创建,并在任何后续调用中保持不变。

【讨论】:

  • 只是一个精度,这仅从 c++11 开始是线程安全的。它不在 c++03 中
  • @wasthishelpful 好吧,我专注于当前的标准,而不是长辈的缺陷。
  • 我也是 :) 但我们不是每个人 ;)
  • @wasthishelpful 坚持老年人标准似乎是徒劳的(爷爷说!)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-26
  • 2016-02-19
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
相关资源
最近更新 更多