【问题标题】:Single instance of an object对象的单个实例
【发布时间】:2013-11-28 08:38:22
【问题描述】:

我正在尝试使用 C++11 实现一个类似单例的对象。我从另一个用户那里得到了这个例子。

它使用构造函数和复制构造函数私有和默认创建一个对象,以及一个返回静态对象的 instance() 函数。

据我了解,这应该会阻止创建此对象的两个实例。但正如您在我的 main.cpp 中看到的那样,我创建了两个实例,它编译并运行。

我的对象创建错误还是什么?没看懂。

object.hpp:

#ifndef OBJECT_H
#define OBJECT_H

#include <iostream>
using namespace std;

class Object
{
private:
   Object() = default;
   Object(const Object&) = delete;
public:
   // Singleton in C++11
   static Object& instance() { static Object z; return z; }
};

#endif // OBJECT_H

main.cpp:

#include "object.hpp"

int main() 
{
    Object* object = new Object();
    object->instance();

    Object* object2 = new Object();
    object->instance();

    return 0;
}

【问题讨论】:

  • 也许这是= default的怪异规则之一。如果我使用 Object(){} 而不是 Object() = default; 我会得到想要的结果(new 不起作用。)
  • 准确使用术语:“它使用构造函数和副本创建对象......”。实际上它创建了一个类:)。也许命名一个类“对象”不是最好的主意;)
  • 你是对的,alfC,如果我使用Object() {},我的编译器也会抱怨new 命令。关于= default还有更奇怪的规则吗?

标签: c++11 singleton private-constructor


【解决方案1】:

当我尝试编译您的代码时,我从编译器中得到一个正确的错误:

main.cpp:错误:调用类“对象”的私有构造函数 Object* ob1= new Object() ;

所以我无法使用new 创建两个对象。

【讨论】:

  • 谢谢,但如果我在 Ideone 上编译它,它也成功了。见ideone.com/1g4ziY
  • 恶心。我会向他们提交错误报告。
  • 是的,我会这样做的。并尝试一些不同的 c++11 编译器。非常感谢!
【解决方案2】:

首先,main 中的代码无法编译。 Object 默认构造函数是私有的,所以你不能这样做:

Object* object = new Object();

其次,instance() 是静态的(意味着与任何实例都不相关),不需要从对象中调用它,类名就足够了:

Object& theInstance = Object::instance();

最后,实例的代码是:

static Object& instance()
{
    static Object z;
    return z;
}

没关系。 C++ 函数中的static 变量意味着对象被实例化一次:当函数第一次运行时。那么z 不会在函数结束时被销毁(与其他所谓的局部变量相反)并且会被重新用于instance 的下一次调用。

所以第一次打电话给instance

  • z 已创建
  • zz 返回

下次通话时:

  • z 被退回

单例是一个类,它意味着只会创建一个实例。您可以使用以下方法验证对象是否相同:

Object& a = Object::instance();
Object& b = Object::instance();

std::cout << &a << std::endl;
std::cout << &b << std::endl;

ab 应该有相同的内存地址。

这是单例的预期行为:如果多次调用对象构造函数 (instance),将返回相同的实例。

正如你所说,instance 实际上阻止创建两个Object。也许您希望您的程序在第二次调用instance 时返回一些错误。如果您不希望出现这种行为,您必须自己使用expections 或返回NULL。然而,您编写的代码显示了在 C++ 中完成单例的经典方式。

【讨论】:

  • 非常感谢您的详细解释。
  • @Smii 没问题! :)
猜你喜欢
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 2011-06-14
相关资源
最近更新 更多