Singleton Design Pattern - Explicitly stating a Constructor outside the class
我试图实现单例模式,假设只使用私有构造函数、类的私有实例和公共静态方法返回实例。但是我在Visual Studio中遇到了以下代码的错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // 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未解析的外部符号"private:ouu thiscall singleton::singleton(void)"(?"public:static class singleton*uu cdecl singleton::getInstance(void)"(函数"public:static class singleton*u cdecl singleton::getInstance(void)"中引用的?0singleton@@aae@xz)(?getInstance@singleton@@sapav1@xz)
然后我解决了这个错误,但在类外部重写了构造函数。
1 2 | Singleton::Singleton() { } |
我想知道错误的原因以及为什么需要在类外部显式地编写构造函数。
在类中,只声明了构造函数,没有定义。定义包括函数体。不管您是在类中内联定义它,还是在类外部(如您所做的)定义它都无关紧要,但有一点不同的是,对于类中的定义,它是隐式的
其他新闻:
单子函数通过避免静态初始化顺序的错误来改进全局变量,但是在不可见的通信线路和副作用方面也有相同的问题。最好避免。
如果在相应的全局变量被销毁后不需要单例来持久化,那么只需使用简单的Meyers'singleton。
这是梅耶斯的单曲:
1 2 3 4 5 6 7 8 9 10 11 12 | class Foo { private: Foo() {} public: static auto instance() -> Foo& { static Foo the_instance; return the_instance; } }; |
默认构造函数需要一个主体:
你可以改变
1 | Singleton(); |
到
1 | Singleton(){}; |
在课堂上,它应该是有效的。
帕加达拉是对的。缺少构造函数定义,因此链接器错误
在迈耶单例的发展过程中,我更喜欢值语义单例,原因如下代码所述:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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()); } |