K, what i have here is a base class and numerous derived classes. below the base class, in the same file, i have a couple objects responsible for registering the derived objects in a map object, with std::string indices, and then an object that will instantiate the objects, given a valid string index. To register a class object, i declare an object of type DerivedRegister in the private members of the derived class, with a template parameter of the class, and then call it's constructor outside the class. Simple enough right? wrong. Because of the way the objects are set up and declared, i keep getting syntax errors when tweaking the base class ever so sligthly. Here is my base.h :
#ifndef BASE_H
#define BASE_H
#include <map>
#include <string>
#include <fstream>
using namespace std;
class base{
#define DECLARE_ENTITY(T) static DerivedRegister<T> reg;
#define LINK_ENTITY(T, name) DerivedRegister<T> T::reg(name);
public:
int getMeh() {return m_meh;}
virtual void GetParams(fstream & stream);
protected:
int m_meh;
string m_EntityName;
};
template<class T> base * createT() {return new T;}
class BaseFactory{
public:
typedef map<string, base *(*)()> map_type;
static base * createInstance(const string & s) {
if ( !getMap()->count(s) )
return NULL;
map_type::iterator it = getMap()->find(s);
return it->second();
}
protected:
static map_type * getMap() {
if(!m_Map) {m_Map = new map_type;}
return m_Map;
}
private:
static map_type * m_Map;
};
template<class T>
class DerivedRegister : BaseFactory {
public:
DerivedRegister(std::string const & s)
{
getMap()-> insert( pair<string, base*(*)()> (s, &createT<T>));
}
};
BaseFactory::map_type * BaseFactory::m_Map = new map_type();
#endif
here is base.cpp when i'm trying to define a member of base:
#include "base.h"
void base::GetParams(fstream & stream)
{
getline(stream, m_EntityName, ' ');
}
however, for some reason, i get this error message:
base.cpp Line 5 : multiple definition of BaseFactory::m_Map
main.cpp Line 11: first defined here
here is my main.cpp where i was testing out the instantiator:
#include <iostream>
#include <vector>
using namespace std;
#include "base.h"
#include "derived.h"
#include "second.h"
#include "third.h"
#include "fourth.h"
int main()
{
BaseFactory yosh;
vector<base *> meh;
for(int i = 0; i < 20; i++)
{
if(i % 4 == 0)
meh.push_back(yosh.createInstance("derived"));
else if( i % 4 == 1)
meh.push_back(yosh.createInstance("second"));
else if( i % 4 == 2)
meh.push_back(yosh.createInstance("third"));
else
meh.push_back(yosh.createInstance("fourth"));
}
for(int i = 0; i < (int) meh.size(); i++)
{
if(meh[i])
cout << meh[i]->getMeh() << "\n";
else
cout << "invalid\n";
}
for(int i = 0; i < (int) meh.size(); i++)
{
if(meh[i]) delete meh[i];
}
return 0;
}
derived, second, third, and fourth are all just test classes that are the same except for there constructors which assign different values to m_Meh. It was very enlightening. Anyway, the problem i'm having with this error, is that the moment i omit that virtual function, GetParams from the base class, and then omit basically everything within the base.cpp file, it compiles and works just fine. so why is it that when i try and add a method to the base class, i get errors about the redefinition of m_Map?
EDIT: i realized just now that the map of the basefactory might need some clarification. the m_map object in there has indices of type std::string, and then the indices refer to pointers to functions. the function is defined just above the class there. when a derived class is registered, they pass in the template parameter to their own class, and a const string. these are used in a new index of the map object where the const string and the templated function pointer are paired together. then anytime i call the member create instance, it passes in the const string, sees if there is a valid index, and if there is, it returns the function at that index, which is called and returns a new instance of the object registered to that const string.