2016-05-16 2 views
2

Я реализую потокобезопасный синглтон. Но этот аспект (singleton & thread-safe) не является частью моего вопроса.C++ singleton, странная ошибка

Сравните два кода. Код 1:

#include <iostream> 
using namespace std; 
class DataLocation { 
private: 
    DataLocation(std::string) { 
    } 
public: 
    DataLocation& getInstance() { 
    std::string s = " "; 
    static DataLocation instance(s); 
    return instance; 
    } 
}; 
int main() { 
} 

и код 2:

#include <iostream> 
using namespace std; 
class DataLocation { 
private: 
    DataLocation() { 
    } 
public: 
    DataLocation& getInstance() { 
    static DataLocation instance();  
    return instance; 
    } 
}; 
int main() { 
} 

код 1 компилируется нормально. Код 2 дает следующее сообщение об ошибке:

15_singleton.cpp: In member function ‘DataLocation& DataLocation::getInstance()’: 
15_singleton.cpp:15:34: error: cannot declare static function inside another function 
    static DataLocation instance();  
           ^
15_singleton.cpp:16:12: error: invalid initialization of non-const reference of type ‘DataLocation&’ from an rvalue of type ‘DataLocation (*)()’ 
    return instance; 
      ^

С моей точки зрения единственное различие заключается в том, что частный конструктор имеет один, соответственно нулевые параметры.

Как я могу помочь компилятору понять, что я не определяю ничего нового, но я просто вызываю конструктор? Компилятор может понять это, когда есть один параметр.

+2

Или используйте фигурные скобки. – MikeMB

+1

О вашей потоковой части, прочитайте на C++ гарантии времени и порядка статичности. – deviantfan

+0

@MikeMB: что вы имеете в виду с фигурными фигурками _use? – LiPo

ответ

5

Снимите кронштейны

static DataLocation instance; 

Чтобы создать экземпляр с помощью конструктора по умолчанию.

В качестве альтернативы используйте форматированную форму.

static DataLocation instance {}; 
+0

@LiPo Это совершенно «логично»; MVP - это хорошо определенное языковое правило. –

+2

Определенное определение не обязательно логично. один параметр: foo (param), нет параметра foo(). это для меня логично. bu мы все разные, и у нас разные логики. – LiPo

1

Метод getInstance() должен быть объявлен как статический.

+0

Я бы также определил его как статический, но я использовал эту [модель] (http://stackoverflow.com/a/19907903), а модель получила +33 ... и я 'новичок – LiPo

+0

@Niall: Нет никакой двусмысленности. Сюрприз для некоторых? Конечно.Но по определению нет никакой двусмысленности. BTW, наиболее неприятный синтаксический разбор относится к «A a (B())». Это вызвано теми же языковыми правилами, что и сюрприз новичка после использования неправильного синтаксиса декларатора. –

+1

@LiPo: Я не делал ни слова, но пока Радек прав, он не отвечает на вопрос. – MikeMB

2
static DataLocation instance = DataLocation(); 

или

static DataLocation instance; 

И вы, вероятно, хотите объявить DataLocation& getInstance(); как метод static.

+4

Не знаете, почему вам нужна первая версия. Тем более что для одиночного элемента вы обычно отключите конструктор копирования, поэтому первая версия не должна компилироваться. – Galik

2

Вы используете скобки () при объявлении

static DataLocation instance(); 

которого намерения создать как объект. Но это просто объявление функции. И вы не можете создать функцию static внутри какой-либо другой функции не static. Это то, к чему относится ваша ошибка.

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