我正在使用Cocos2D,我创建了一个Singleton C ++类,用于存储游戏设置信息。这就是我班上的样子:
#include <cstddef>
#ifndef __pyramidofdoom__GameSettings__
#define __pyramidofdoom__GameSettings__
#endif /* defined(__pyramidofdoom__GameSettings__) */
class GameSettings {
private:
static GameSettings* mGameSettings;
GameSettings(){ mGameSettings = this; }
int rowSelected = 0;
public:
GameSettings *getInstance() {
if (mGameSettings == NULL)
mGameSettings = new GameSettings();
return mGameSettings;
};
int getSelectedRow() { return rowSelected; }
void setSelectedRow(int row) { rowSelected = row;}
};
这就是我在cocos2D mm文件中使用它的方法:
GameSettings *gameSettings = gameSettings->getInstance();
if(multi)
gameSettings->setSelectedRow(3);
else
gameSettings->setSelectedRow(1);
似乎基本上足以使一切正常。
这是我现在尝试构建时遇到的错误:
Undefined symbols for architecture i386:
"GameSettings::mGameSettings", referenced from:
GameSettings::getInstance() in GameLayer-E06C3150ABD8625A.o
GameSettings::GameSettings() in GameLayer-E06C3150ABD8625A.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我确保在Build Phases下为Compile Source包含了cpp / h文件。我还添加了libc ++ Library,看看是否可以修复它。
答案 0 :(得分:1)
您已声明mGameSettings
,但未对其进行定义。您需要在源文件中定义:
GameSettings* mGameSettings = NULL;
或者,您可以将其设为本地静态变量:
GameSettings *getInstance() {
static GameSettings instance;
return instance;
}
它具有不泄漏内存和线程安全的优点(在符合C ++ 11的编译器中),如果这对您很重要。
或者,摆脱单身人士。它们几乎从来不是一个好主意(What is so bad about singletons?),特别是在C ++中,除了模式中固有的过度耦合和受限制的可测试性之外,还会遇到许多生命周期问题。
另外,不要为包含警卫使用保留名称:What are the rules about using an underscore in a C++ identifier?更重要的是,它应该保护整个标题 - 你的不做任何事情。
答案 1 :(得分:1)
您#import
并使用cpp类的任何标头或实现也必须使用.mm
扩展名。
因此,如果您导入GameSettings.h并使用GameLayer.m中的GameSettings cpp类,则必须将其重命名为GameLayer.mm。
您可能希望改为使用Objective-C类。理想情况下完全废弃整个单身人士。例如,应用程序代理中的引用也可以在应用程序启动时实例化设置类。