2016-05-16 100 views
2

我正在实现一个线程安全的单例。但是这方面(单线​​程&线程安全)不是我的问题的一部分。C++单例,奇怪的错误

比较两个代码。代码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:你用_大括号_指什么意思? – LiPo

回答

5

删除括号,

static DataLocation instance; 

要使用默认的构造函数创建实例。

或者,使用加载形式的初始化。

static DataLocation instance {}; 
+0

@ LiPo这完全是“合乎逻辑的”; MVP是一个明确的语言规则。明确定义的 –

+2

不一定合乎逻辑。一个参数:foo(param),没有参数foo()。这对我来说是合乎逻辑的。我们都是不同的,我们有不同的逻辑 – LiPo

1

方法getInstance()应该声明为静态。

+0

我也将它定义为静态的,但我用这[模型](http://stackoverflow.com/a/19907903),和模型得到+33 ...和我'初学者 – LiPo

+0

@Niall:没有歧义。一些惊喜?当然。但根据定义,不存在歧义。顺便说一句,最令人头疼的解析涉及'A a(B());'。在使用错误的声明语法之后,它与新手的意外相同的语言规则。 –

+1

@ LiPo:我没有downvote,但虽然Radek是对的,但它并没有回答这个问题。 – MikeMB

2
static DataLocation instance = DataLocation(); 

static DataLocation instance; 

而且你可能会想声明DataLocation& getInstance();static方法。

+4

不知道你为什么想要第一个版本。特别是对于单例,通常禁用复制构造函数,因此第一个版本不应该编译。 – Galik

2

您正在使用括号()同时宣布

static DataLocation instance(); 

您打算创建一个对象。但是,只是一个函数声明。并且您不能在其他某些非static函数内创建static函数。这就是你的错误所指的。