2014-02-10 50 views
2

我有一個關於工廠模式的問題。我編寫了一個工廠,它有一個名爲registerIt的靜態函數。它接受一個類名字符串和一個指向任何類的創建者函數的指針。註冊類本身到工廠

static void CharacterFactory::registerit(const std::string& classname, Creator creator) 
{ 
    table[classname] = creator; 
} 

該表是

std::map<std::string, CharacterFactory::Creator> CharacterFactory::table; 

創作者

typedef std::auto_ptr<Actor> Type; 
typedef Type (*Creator)(); 

演員是基類

的類本身具有功能用於登記。例如類「播放器」

static void registerToFactory(){ 
    CharacterFactory::registerit("Player",&create); 
    std::cout<<"player created"<<std::endl;  
    } 

我的問題是,我怎麼能告訴類註冊自己到靜態工廠?如果我在主類中調用registerToFactory,一切正常。但我想更動態地做到這一點,所以我只需要在新類中更改代碼,而不是在代碼中的任何地方。

整個下面的代碼:

Factory.h:

#pragma once 
#include "Actor.h" 
#include <string> 
#include<map> 
namespace Character{ 
class Actor; 
class CharacterFactory 
{ 

public: 
typedef std::auto_ptr<Actor> Type; 
typedef Type (*Creator)(); 

CharacterFactory(void); 
~CharacterFactory(void); 

Type create(const std::string& classname); 
static void registerit(const std::string& classname, Creator creator); 

private: 
static std::map<std::string, Creator> table; 
}; 
} 

演員:

#pragma once 
#include<string> 
#include"CharacterFactory.h" 
#include<iostream> 
namespace Character{ 

class Actor 
{ 
public: 

static Actor* create(){std::cout<<"dummy"<<std::endl;return NULL;}; 
static Actor* create(int dmg){std::cout<<"dummy"<<std::endl;return NULL;}; 

Actor(void):damage(0),healthPoints(0),lastUpdate(0){}; 
Actor(int dmg):damage(dmg){}; 
~Actor(void); 

virtual void update(void)=0; 
virtual void update(int deltaMillis)=0; 

protected: 

int lastUpdate; 


//Attribute 
int healthPoints; 
int damage; 
//Amor amor; 
//Weapon weapon; 
//Ai ai; 


//Networking 

}; 

} 

球員:

#pragma once 
#include "Actor.h" 
#include <stdio.h> 
#include "CharacterFactory.h" 

namespace Character{ 
#ifndef PLAYER_H 
#define PLAYER_H 
class Player:public Actor 
{ 
public: 

void update(void){}; 
void update(int deltaMillis){}; 


static std::auto_ptr<Actor> create(){ 
    return std::auto_ptr<Actor>(new Player); 
} 
Player(void); 

~Player(void); 
static void registerToFactory(){ 
     CharacterFactory::registerit("Player",&create); 
     std::cout<<"player created"<<std::endl;  
    } 
inline int getDamage(void){ return damage;}; 
}; 
#endif 
} 

我希望你能幫助我:)

+0

你可以在一個靜態對象(你必須寫一個新類)的構造函數中完成它。然後,每次添加新課程時,您都不必觸摸主要功能。你仍然需要在某個地方定義這些靜態對象,每個類都有一個。 –

+0

如果我在player.h中的所有代碼之後插入'static Player player',我在xtree中得到一個錯誤?你能給我舉個例子嗎?我想在它的類或.cpp文件中的某處創建靜態對象 – Christian

+0

我嘗試了一種解決方法。有一個函數'loadCharacters()'。它創建每個Character的靜態對象,所以構造函數被調用。然後我創建了一個工廠實例。在其構造函數中調用該函數。所以我只需要改變函數中的靜態實例。但我有一個工廠對象,我不需要。 – Christian

回答

1

您可以使用靜態變量的構造函數或動態初始化表達式,編譯器將確保在調用main()之前運行。