2016-04-22 2 views
0

Я пытался реализовать одноэлементный шаблон с предположением о простом использовании частного конструктора, частного экземпляра класса и общедоступного статического метода для возврата экземпляра. Но я обнаружил ошибку в следующем коде в Visual StudioSingleton Design Pattern - Явное объявление конструктора вне класса

// Singleton Invoice 
#include <iostream> 
using namespace std; 

class Singleton { 
public: 
    //Public Static method with return type of Class to access that instance. 
    static Singleton* getInstance(); 
private: 
    //Private Constructor 
    Singleton(); 
    //Private Static Instance of Class 
    static Singleton* objSingleton; 
}; 

Singleton* Singleton::objSingleton = NULL; 

Singleton* Singleton::getInstance() { 
    if (objSingleton == NULL) { 
    //Lazy Instantiation: if the instance is not needed it will never be created 
    objSingleton = new Singleton(); 
    cout << "Object is created" << endl; 
    } 
    else 
    { 
    cout << "Object is already created" << endl; 
    } 
    return objSingleton; 
} 

int main() { 
    Singleton::getInstance(); 
    Singleton::getInstance(); 
    Singleton::getInstance(); 
    return 0; 
} 

Ошибка, как:

LNK2019 неразрешенный внешний символ "частный: __thiscall Singleton :: Singleton (аннулируются)" (?? 0Singleton @@ AAE @XZ) упоминается в функции "общественность: статический класс Singleton * __cdecl Singleton :: деЫпзЬапс (аннулируется)" (деЫпзЬапсе @ Singleton @@ SAPAV1 @ XZ)

Тогда я решил ошибку, но переписывания конструктора вне класса

?
Singleton::Singleton() { 
} 

Я хотел бы знать причину ошибки и почему конструктор должен быть явно написан вне класса.

+0

Я думаю, это потому, что вы объявили constuctor, но не реализовали его. Кстати, вы случайно участвуете в студенческом колледже Fanshawe? Любопытно – kburlz

+0

Вы создаете указатели на свой метод getInstance и одноэлементный объект. Вы пробовали разыгрывать в основном? – almostcolin

+1

@kburlz Я студент в Университете Бриджпорта: D, Это был пример моего профессора, найденного в Интернете, чтобы научить нас синглтонному шаблону, поэтому, когда я писал его самостоятельно, я столкнулся с проблемой и был любопытен. Думаю, вас можно было бы обучить по тому же примеру: D –

ответ

3

В классе конструктор был объявлен, не определен. Определение включает в себя тело функции. Неважно, определяете ли вы его встроенный в классе или вне класса (как и вы), но одна небольшая разница заключается в том, что с определением в классе это неявно inline.


В других новостях:

  • Синглтоны улучшения глобальных переменных, избегая, например, фиаско порядка статической инициализации, но имеют те же проблемы в отношении невидимых линий связи и побочных эффектов. Лучше всего избегать.

  • Если вам не нужен синглет, который сохранится после того, как соответствующая глобальная переменная будет уничтожена, просто используйте простой синглет Meyers.

Вот Мейерс синглтон:

class Foo 
{ 
private: 
    Foo() {} 
public: 
    static auto instance() 
     -> Foo& 
    { 
     static Foo the_instance; 
     return the_instance; 
    } 
}; 
+0

Итак, правильно ли я предполагаю, что статическая переменная Foo создается только при вызове функции? В отличие от обычного синглтона, где создается статическая переменная, и неэффективность вводится, когда переменная никогда не используется? –

+0

@PagadalaVikramaditya: Да, это так. Он создается в первый раз, когда выполнение проходит через объявление, которое является первым вызовом 'instance'. И в C++ 11 и более поздних версиях это даже поточно-безопасное. –

3

конструктор по умолчанию требует тело:

Вы можете изменить

Singleton(); 

в

Singleton(){}; 

внутри класса и он должен работать.

0

В эволюции одноточечного Мейера, я предпочитаю ценностно-смысловая синглтон, по причинам, указанным в коде ниже:

class singleton 
{ 
    // private implementation 
    struct impl { 
    void do_something() { } 
    }; 

    // private decision as to whether it's really a singleton and what its lifetime 
    // will be 
    static impl& instance() { static impl _impl; return _impl; } 

public: 
    // public interface defers to private lifetime policy and implementation 
    void do_something() { instance().do_something(); } 
}; 

void something(singleton s) 
{ 
    s.do_something(); 
} 

int main() 
{ 
    // we can now pass singletons by value which gives many benefits: 
    // 1) if they later become non-singletons, the code does not have to change 
    // 2) the implementation can be private so better encapsulation 
    // 3) we can use them in ADL more effectively 
    auto x = singleton(); 
    something(x); 
    something(singleton()); 
} 
0

Pagadala является правильным. Определение конструктора отсутствует, поэтому ошибка компоновщика

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