单例类的实现(1)

 

          游戏引擎中经常用到单例(singleton)类,即应用程序只存在该类的一个实例,下面是它的实现方式:

1、c++ professional中的单例日志类:定义一个protected的static Logger sInstance;然后通过public静态函数

static Logger& instance();返回sInstance,从而实现对该类中函数的访问。同时,该类的构造函数是私有的,我们不能通过构造函数创建该类的实例。

 

ContractedBlock.gif ExpandedBlockStart.gif Code
/**
 * Logger.h
 *
 * Definition of a true singleton logger class.
 
*/
#include 
<iostream>
#include 
<fstream>
#include 
<vector>

class Logger
{
 
public:
  
static const std::string kLogLevelDebug;
  
static const std::string kLogLevelInfo;
  
static const std::string kLogLevelError;

  
// Returns a reference to the singleton Logger object
  static Logger& instance();

  
// Logs a single message at the given log level
  void log(const std::string& inMessage, 
       
const std::string& inLogLevel);

  
// Logs a vector of messages at the given log level
  void log(const std::vector<std::string>& inMessages, 
       
const std::string& inLogLevel);

 
protected:
  
// Static variable for the one-and-only instance  
  static Logger sInstance;

  
// Constant for the file namename
  static const char* const kLogFileName;

  
// Data member for the output stream
  std::ofstream mOutputStream;

 
private:
  Logger();
  
~Logger();

};

 

ContractedBlock.gif ExpandedBlockStart.gif Code
/**
 * Logger.cpp
 *
 * Implementation of a singleton logger class.
 
*/
#include 
<string>
#include 
"Logger.h"

using namespace std;

const string Logger::kLogLevelDebug = "DEBUG";
const string Logger::kLogLevelInfo = "INFO";
const string Logger::kLogLevelError = "ERROR";

const char* const Logger::kLogFileName = "log.out";

// The static instance will be constructed when the program starts and
// destructed when it ends.
Logger Logger::sInstance;

Logger
& Logger::instance()
{
  
return sInstance;
}

Logger::
~Logger()
{
  mOutputStream.close();
}

Logger::Logger()
{
  mOutputStream.open(kLogFileName, ios_base::app);
  
if (!mOutputStream.good()) {
    cerr 
<< "Unable to initialize the Logger!" << endl;
  } 
}

void Logger::log(const string& inMessage, const string& inLogLevel)
{
  mOutputStream 
<< inLogLevel << "" << inMessage << endl;
}

void Logger::log(const vector<string>& inMessages, const string& inLogLevel)
{
  
for (size_t i = 0; i < inMessages.size(); i++) {
    log(inMessages[i], inLogLevel);
  }
}


int main(int argc, char** argv)
{
  Logger::instance().log(
"test message", Logger::kLogLevelDebug);

  vector
<string> items;
  items.push_back(
"item1");
  items.push_back(
"item2");

  Logger::instance().log(items, Logger::kLogLevelError);
}

 

 2、Game AI ...中的代码:

和前面的基本一样,但是在getinstance中来定义一个指向该类的静态变量,效果和上面一样,该函数第一次调用时候,会创建该静态变量。

 

ContractedBlock.gif ExpandedBlockStart.gif Code
class VisitBankAndDepositGold : public State<Miner>
{
private:
  
  VisitBankAndDepositGold(){}

  
//copy ctor and assignment should be private
  VisitBankAndDepositGold(const VisitBankAndDepositGold&);
  VisitBankAndDepositGold
& operator=(const VisitBankAndDepositGold&);
 
public:

  
static VisitBankAndDepositGold* Instance();

  
virtual void Enter(Miner* miner);

  
virtual void Execute(Miner* miner);

  
virtual void Exit(Miner* miner);
};





//----------------------------------------methods for VisitBankAndDepositGold

VisitBankAndDepositGold
* VisitBankAndDepositGold::Instance()
{
  
static VisitBankAndDepositGold instance;

  
return &instance;
}

void VisitBankAndDepositGold::Enter(Miner* pMiner)
{  
  
//on entry the miner makes sure he is located at the bank
  if (pMiner->Location() != bank)
  {
    cout 
<< "\n" << GetNameOfEntity(pMiner->ID()) << "" << "Goin' to the bank. Yes siree";

    pMiner
->ChangeLocation(bank);
  }
}


void VisitBankAndDepositGold::Execute(Miner* pMiner)
{
  
//deposit the gold
  pMiner->AddToWealth(pMiner->GoldCarried());
    
  pMiner
->SetGoldCarried(0);

  cout 
<< "\n" << GetNameOfEntity(pMiner->ID()) << "" 
       
<< "Depositing gold. Total savings now: "<< pMiner->Wealth();

  
//wealthy enough to have a well earned rest?
  if (pMiner->Wealth() >= ComfortLevel)
  {
    cout 
<< "\n" << GetNameOfEntity(pMiner->ID()) << "" 
         
<< "WooHoo! Rich enough for now. Back home to mah li'lle lady";
      
    pMiner
->GetFSM()->ChangeState(GoHomeAndSleepTilRested::Instance());      
  }

  
//otherwise get more gold
  else 
  {
    pMiner
->GetFSM()->ChangeState(EnterMineAndDigForNugget::Instance());
  }

}


void VisitBankAndDepositGold::Exit(Miner* pMiner)
{
  cout 
<< "\n" << GetNameOfEntity(pMiner->ID()) << "" << "Leavin' the bank";
}

 

 

 

posted on 2009-11-20 20:48 迈克老狼 阅读( ...) 评论( ...)   编辑 收藏

转载于:https://www.cnblogs.com/mikewolf2009/articles/1607211.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值