之前也总写单例,不过基本上是网上直接拽,这次也是网上直接拽,却出了问题。。
class UserData { private: UserData(){} static UserData *my_pInstance; public: static UserData* myInstance() { if (my_pInstance == NULL) { my_pInstance = new UserData(); } return my_pInstance; } }; UserData* UserData::my_pInstance = NULL;
这是头文件,然后我再.cpp里面include了头文件,其他地方引用头文件并初始化,就报错了:
duplicate symbol _a in: /Users/zzz/Library/Developer/Xcode/DerivedData/CocosProject1-evrazoxxksceilbxnvvkcbfiidej/Build/Intermediates/CocosProject1.build/Debug/CocosProject1 Mac.build/Objects-normal/x86_64/UserData.o /Users/zzz/Library/Developer/Xcode/DerivedData/CocosProject1-evrazoxxksceilbxnvvkcbfiidej/Build/Intermediates/CocosProject1.build/Debug/CocosProject1 Mac.build/Objects-normal/x86_64/HelloWorldScene.o duplicate symbol __ZN8UserData12my_pInstanceE in: /Users/zzz/Library/Developer/Xcode/DerivedData/CocosProject1-evrazoxxksceilbxnvvkcbfiidej/Build/Intermediates/CocosProject1.build/Debug/CocosProject1 Mac.build/Objects-normal/x86_64/UserData.o /Users/zzz/Library/Developer/Xcode/DerivedData/CocosProject1-evrazoxxksceilbxnvvkcbfiidej/Build/Intermediates/CocosProject1.build/Debug/CocosProject1 Mac.build/Objects-normal/x86_64/HelloWorldScene.o ld: 2 duplicate symbols for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
看上去好像是重定义了之类的问题,后来百度找到原因引用一段话:
静态成员变量实际上是全局变量, 所以需要像全局变量一样定义以分配存储空间。
举个例子, 比如有一个类A声明在了A.h头文件中, 这个类A有一个静态变量 a。
这时有两个CPP文件包含了这个头文件,但这两个CPP文件编译后的输出中都不包含这个静态变量的实际定义而仅仅是标记这个变量符号为外部符号:因为这两 个CPP文件无法协调到底谁来实际生成这个变量的定义并分配空间,所以只好谁也不管这事, 你需要手动指定到底在哪个CPP里包含这个变更的实际分配。
意思就是全局变量是不能包含在两个文件中的,类似于类外写一个int i = 0;然后有两个文件包含这个头文件,就会报错(如果只有一个包含不报错)
但是想想又不对,我写的是静态变量啊,静态变量不就应该类外初始化么,最后没办法把静态变量初始化UserData* UserData::my_pInstance = NULL;挪到了cpp里面,就奇迹的通过了。
= =这个问题感觉还是很奇怪,就先这么记录一下,后面想明白了再回来改。。
至于全局变量int i = 0,写在类外的做法是加命名空间或者extern,有待实践。