C++单点与新算子

C++单点与新算子,c++,class,scope,singleton,C++,Class,Scope,Singleton,您好,我有一段代码,这是一个单例类,我相信它使用了“new”和一些其他作用域和静态限定符,这种方式我以前从未见过。因为我不知道它叫什么,所以我找不到任何关于它的用途的信息。代码如下: 在myClass.h文件中,我有 class myClass { private: static myClass sm_myClass; myClass(); public: static void Create(void); }; 在myClass.cpp中,我有 #include "m

您好,我有一段代码,这是一个单例类,我相信它使用了“new”和一些其他作用域和静态限定符,这种方式我以前从未见过。因为我不知道它叫什么,所以我找不到任何关于它的用途的信息。代码如下:

在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-第6行myClass myClass::sm_myClass发生了什么;.cpp文件的

2-第16行新p_myClass myClass发生的情况;.cpp文件的

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


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

1静态成员变量需要在一个编译单元中分配存储空间。cpp/.cxx。这一定义规定:

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


3有时,将全局服务封装到对象中并使用单例可以方便地让该服务的客户端访问它。

1静态成员变量需要在一个编译单元中分配存储。cpp/.cxx。这一定义规定:

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

3有时,将全局服务封装到对象中是很方便的,而使用单例可以为该服务的客户端提供访问该服务的简单方法

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

定义了静态类成员

2-第16行新p_myClass myClass发生的情况;.cpp文件的

指定一个新的位置以重用为p_myClass分配的内存

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

有些情况下,单例可能会派上用场,但一般来说,最好传递接口,而不是将客户机代码与myClass紧密耦合

不要使用new placement new或not来初始化单例实例。改用Scott Meyer的单例实现,它保证了线程安全:

class myClass
{
private:
    myClass();
public:
    static myClass& instance() {
         static myClass theInstance;
         return theInstance;
    }
};
实例将在首次访问实例函数时创建,并在后续调用中保持不变

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

定义了静态类成员

2-第16行新p_myClass myClass发生的情况;.cpp文件的

指定一个新的位置以重用为p_myClass分配的内存

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

有些情况下,单例可能会派上用场,但一般来说,最好传递接口,而不是将客户机代码与myClass紧密耦合

不要使用new placement new或not来初始化单例实例。改用Scott Meyer的单例实现,它保证了线程安全:

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

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

FWIW如果要使用单例,请参阅:您可能还希望读取在程序启动时构造的对象sm_myClass。调用placement new试图在现有对象的基础上构造一个新对象,从而产生未定义的行为。@PeteBecker:实际上,在现有对象上放置new是可以的,但显然不建议这样做。IIRC,只有在依赖析构函数产生一些副作用的情况下,它才是UB。@GManNickG-在有限的情况下,它可能还可以,但这是一种高级技术,在初学者的代码中是完全不合适的。FWIW如果您想使用单例,请参见:您可能还想阅读在程序启动时构造的对象sm_myClass。调用placement new试图在现有对象的基础上构造一个新对象,从而产生未定义的行为。@PeteBecker:实际上,在现有对象上放置new是可以的,但显然不建议这样做。IIRC,只有当你依靠析构函数来获得一些副作用时,它才是UB。@GManNickG-在有限的情况下,它可能还可以,但这是一种高级技术,在初学者的代码中完全不合适。使用新的位置完全不适合这里,没有理由这样做。使用新的位置完全不适合这里,没有理由这样做。只是为了精确,这是自c++11以来线程安全的。它不是在C++中03@wasthishelpful嗯,我关注的是当前的标准,而不是长者的缺陷。我也是:但我们不是所有人;
@爷爷说:“这有用吗?坚持老年人的标准似乎是徒劳的!”!。只是一个精度,这是线程安全的,只有在c++11。它不是在C++中03@wasthishelpful嗯,我关注的是当前的标准,而不是长者的缺陷。我也是:但我们不是所有人@爷爷说:“这有用吗?坚持老年人的标准似乎是徒劳的!”!。