我试图实现单例模式,假设只使用私有构造函数,类的私有实例和公共静态方法来返回实例。但是我在Visual Studio中遇到了以下代码的错误
// 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未解析的外部符号&#34;私人:__ thiscall Singleton :: Singleton(void)&#34; (?? 0Singleton @@ AAE @XZ)在函数&#34中引用; public:static class Singleton * __cdecl Singleton :: getInstance(void)&#34; (?getInstance @ Singleton @@ SAPAV1 @ XZ)
然后我解决了错误,但重写了类
之外的构造函数Singleton::Singleton() {
}
我想知道错误的原因以及为什么需要在类外部显式编写构造函数。
答案 0 :(得分:3)
默认构造函数需要一个正文:
你可以改变
Singleton();
到
Singleton(){};
在课堂内,它应该工作。
答案 1 :(得分:3)
在类中,构造函数仅被声明,未定义。定义包括函数体。无论你是在类中内联还是在类之外定义它都没关系(正如你所做的那样),但有一点不同的是,类中的定义隐含inline
。
在其他新闻中:
单身人士通过避免例如改进全局变量来改进全局变量静态初始化顺序为fiasco,但对于不可见的通信线路和副作用存在同样的问题。最好避免。
如果在销毁相应的全局变量后不需要单例持久化,那么只需使用简单的Meyers单例。
这是迈耶斯的单身人士:
class Foo
{
private:
Foo() {}
public:
static auto instance()
-> Foo&
{
static Foo the_instance;
return the_instance;
}
};
答案 2 :(得分:1)
在 C++11 中,我们可以使用“default”说明符来指示编译器创建构造函数的默认实现。
参考以下对我有用的代码片段:
class Singleton
{
static Singleton* m_instance;
Singleton()=default; /* Note the use of default specifier here*/
public:
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* getInstance()
{
if(!m_instance){m_instance= new Singleton();}
return m_instance;
}
};
答案 3 :(得分:0)
在Meyer's singleton的演变中,我更喜欢价值语义单例,原因如下所示:
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());
}
答案 4 :(得分:0)