2014-02-10 4 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

если я вставляю 'static Player player' после всего кода в player.h, я получаю сообщение об ошибке в xtree? Можете ли вы дать мне пример, пожалуйста? Я хотел бы создать статический объект в своем классе или где-нибудь в .cpp-файле – Christian

+0

Я пробовал обходной путь. Есть функция 'loadCharacters()'. Он создает статические объекты каждого символа, поэтому вызывается конструктор. Затем я создал экземпляр фабрики. В его конструкторе вызывается функция. поэтому мне нужно только изменить статические экземпляры в функции. Но у меня есть фабричный объект, который мне не нужен. – Christian

ответ

1

Вы можете использовать выражение конструктора или динамической инициализации для статической переменной, и компилятор будет обеспечивать выполнение перед вызовом main().

Смежные вопросы