2013-11-28 8 views
0

Я пытаюсь реализовать одноэлементный объект с C++ 11. Я получил этот пример от другого пользователя.Отдельный экземпляр объекта

Создает объект с конструктором и конструктором копирования, как private, так и по умолчанию, а также функцию 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; 
} 
+0

Возможно, это одно из странных правил '= default'. Если я использую 'Object() {}' вместо 'Object() = default;' Я получаю желаемый результат ('new' не работает.) – alfC

+0

Будьте точны с терминологией:« Он создает объект с конструктором и копия ... ». На самом деле он создает класс :). И, возможно, присвоение имени классу «Объект» - не лучшая идея из-за этого;) –

+0

Вы правы, alfC, если я использую 'Object() {}' мой компилятор, также жалуется на команду 'new'. Есть ли более странные правила относительно '= default'? – Smii

ответ

1

Сначала ваш код в main не компилируется. Object default constructor является закрытым, поэтому вы не сможете сделать:

Объект * object = new Object();

Во-вторых, в качестве instance() статичен (средство не связано ни с каким, например) нет необходимости вызывать его из объекта, имя класса достаточно:

объектов & theInstance = Object :: экземпляр();

Наконец, код экземпляра является:

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

Это нормально. A static переменная в функции C++ означает, что объект инициализируется один раз: когда функция запускается в первый раз. Тогда z не будет уничтожен в конце функции (в отличие от других так называемых локальных переменных) и будет повторно использоваться для следующих вызовов instance.

Так что при первом вызове instance:

  • z создается
  • z г возвращается

В следующих вызовах:

  • z возвращается

Singleton - это класс, который подразумевает создание только одного экземпляра.Вы можете проверить объекты одинаковы с:

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

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

a и b должны иметь один и тот же адрес памяти.

Это ожидаемое поведение одноэлементного: если функция построения объекта (instance) вызывается несколько раз, тот же экземпляр будет возвращен.

Как вы сказали, instance фактически предотвращает создание двух Object. Возможно, вы ожидали, что программа вернет некоторую ошибку при втором вызове instance. Если вы этого не сделаете, вам придется сделать это самостоятельно, используя Ожидания или возврат NULL. Тем не менее, код, который вы написали, показывает, как классические способы синглтонов выполняются на C++.

+0

Большое спасибо за подробное объяснение. – Smii

+0

@Smii Нет проблем! :) –

2

Когда я пытаюсь скомпилировать код, я получаю правильную ошибку от компилятора:

main.cpp: error: calling a private constructor of class 'Object' Object* ob1= new Object() ;

Поэтому я не смог бы создать два объекта, используя new.

+0

Спасибо, но если я скомпилирую его на Ideone, он преуспел. см. http://ideone.com/1g4ziY – Smii

+0

Icky. Я бы написал с ними отчет об ошибке. – woolstar

+0

Да, я сделаю это. И попробуйте несколько компиляторов C++ 11. Большое спасибо! – Smii

Смежные вопросы