“确保一个类只有一个实例,并为其提供一个全局访问入口。”
下面是无法保证线程安全的
class FileSystem
{
public:
static FileSystem& instance()
{
//Lazy initialize.
if (instance_ == NULL)
{
instance_ = new FileSystem();
}
return *instance_;
}
private:
FileSystem() {}
static FileSystem* instance_;
};更现代的版本,可以保证线程安全
class FileSystem
{
public:
static FileSystem& instance()
{
static FileSystem *instance = new FileSystem();
return *instance;
}
private:
FileSystem() {}
};class FileSystem
{
public:
virtual ~FileSystem() {}
virtual char* read(char* path) = 0;
virtual void write(char* path, char* text) = 0;
};为不同的平台定义派生类
class PS3FileSystem : public FileSystem
{
public:
virtual char* read(char* path)
{
// Use Sony file IO API...
}
virtual void write(char* path, char* text)
{
// Use sony file IO API...
}
};
class WiiFileSystem : public FileSystem
{
public:
virtual char* read(char* path)
{
// Use Nintendo file IO API...
}
virtual void write(char* path, char* text)
{
// Use Nintendo file IO API...
}
};将FileSystem变为一个单例
class FileSystem
{
public:
static FileSystem& instance();
virtual ~FileSystem() {}
virtual char* read(char* path) = 0;
virtual void write(char* path, char* text) = 0;
protected:
FileSystem() {}
};
// 不同的平台构造不同的单例对象
FileSystem& FileSystem::instance()
{
#if PLATFORM == PLAYSTATION3
static FileSystem *instance = new PS3FileSystem();
#elif PLATFORM == WII
static FileSystem *instance = new WiiFileSystem();
#endif
return *instance;
}大部分的游戏都不依赖延迟初始化,像这样实现单例模式:
class FileSystem
{
public:
static FileSystem& instance() { return instance_; }
private:
FileSystem() {}
static FileSystem instance_;
};比如日志对象,我们设计成了单例模式,慢慢的后面发现可能需要多个日志,后面成了火葬场。
当出现错误使用方式时,我们能够及时法线。
class FileSystem
{
public:
FileSystem()
{
assert(!instantiated_);
instantiated_ = true;
}
~FileSystem() { instantiated_ = false; }
private:
static bool instantiated_;
};
bool FileSystem::instantiated_ = false;class GameObject
{
protected:
Log& Log() { return log_; }
private:
static Log& log_;
};
class Enemy : public GameObject
{
void doSomething()
{
getLog().write("I can log!");
}
};class Game
{
public:
static Game& instance() { return instance_; }
Log& log() { return *log_; }
FileSystem& fileSystem() { return *files_; }
AudioPlayer& audioPlayer() { return *audio_; }
// Functions to set log_, et. al. ...
private:
static Game instance_;
Log *log_;
FileSystem *files_;
AudioPlayer *audio_;
};这样起码比一大堆单例要好得多。
Game::instance().getAudioPlayer().play(LOUD_BANG);