R
Ryan Mitchley
Hi all
I have code for an object factory, heavily based on an article by Jim Hyslop
(although I've made minor modifications). The factory was working fine using
g++, but since switching to the Intel compiler it has stopped working. I
think the singleton pattern static instance thing may be at the root of the
problem, but I'm not sure. I had to add calls to instance() in regCreateFn,
which gets the behaviour more in line with what I was expecting during
static initialization (the objects all register with the same registry). I
have tried playing with the MS compatibility options of the Intel compiler,
with no success.
The problem occurs when I make a call to manufacture a given object: a
totally different instance of the factory and registry are used (I have
checked this by printing out pointers).
A typical call to the manufacture method would be:
shared_ptr<CAngle3D> newB = boost::shared_polymorphic_cast<CAngle3D>
(objectFactory<CBase>::instance().manufacture("CAngle3D"));
This fails, since the objectFactory<CBase>::instance() returns a valid
factory, but one with no items in the map of create functions (i.e. it is a
different one to that used when registering the create functions in the
static initalizers).
In this example, the first section of the header for CAngle3D is as follows:
class CAngle3D : public CBase
{
public:
// Tell the Object Factory about this class
//FACTORY_DECLARE_CLASS(CAngle3D
static registerInFactory<CBase, CAngle3D> regClass;
and the following is placed into the cpp for CAngle3D:
// Register class with Object Factory
//FACTORY_REGISTER_CLASS(CAngle3D)
registerInFactory<CBase, CAngle3D> CAngle3D::regClass("CAngle3D");
The complete CFactory.h listing is pasted at the end of this email. You will
notice that there is a large amount of debugging info being output.
The output of my program, when it starts up, is as follows: (Notice
especially the memory addresses, that change when the program tries to
manufacture a CAngle3D object)
$ ./TestMathCore
Constructor: objectFactory for class CBase
Registering create function for "CAngle3D"
Registry size = 1(0046FBD0)
Registering clone function for "CAngle3D"
registerInFactory: "CAngle3D"
Constructor: objectFactory for class CBase
Registering create function for "CFrequency"
Registry size = 2(0046FBD0)
Registering clone function for "CFrequency"
registerInFactory: "CFrequency"
Constructor: objectFactory for class CBase
Registering create function for "CList"
Registry size = 3(0046FBD0)
Registering clone function for "CList"
registerInFactory: "CList"
Constructor: objectFactory for class CBase
Registering create function for "CSortableList"
Registry size = 4(0046FBD0)
Registering clone function for "CSortableList"
registerInFactory: "CSortableList"
Constructor: objectFactory for class CBase
Registering create function for "CCollection"
Registry size = 5(0046FBD0)
Registering clone function for "CCollection"
registerInFactory: "CCollection"
Constructor: objectFactory for class CBase
Registering create function for "CAngle"
Registry size = 6(0046FBD0)
Registering clone function for "CAngle"
registerInFactory: "CAngle"
Min resolution = 1, Max resolution = 1000000
Timer setting successful.
The system clock interval is 10 ms.
Adjustment disabled = 1
MathCore Test App
-----------------
CAngle3D
Constructor: objectFactory for class CBase
Registry size = 0(0046FB04)
Contents of Object Factory warehouse:
Trying to manufacture "CAngle3D"
Object Factory 0046FB04: 0 items
objectFactory: Don't know how to manufacture that object type.
Ensure that FACTORY_REGISTER_CLASS is used.
I would *really* appreciate some help! Sorry for the hugely long post . . .
Ryan
// CFactory.h
// object abstract factory template.
// Copyright 2001, Jim Hyslop.
// This file may be freely used, modified and distributed, provided that
// the accompanying copyright notice remains intact.
//
// The object abstract factory template is an implementation of the
// Abstract Class Factory pattern, as a template (see "Design Patterns:
// Elements of Reusable Object-Oriented Software", E. Gamma, R. Helm,
// R. Johnson, J. Vlissides, Addison Wesley [1995] )
//
// To use the template, you need to provide a base class and (optionally)
// a key class. The base class must provide a unique identifier
//
// The key class must be able to be used as a key in a std::map, i.e. it
must
// - implement copy and assignment semantics
// - provide bool operator< () const;
// Default is std::string.
//
// Steps to using the factory:
// 1 - Create the base class and its derivatives
// 2 - Register each class in the factory by instantiating a
// registerInFactory<> template class - do this in one file only (the
// class implementation file is the perfect place for this)
// 3 - create the object by calling create() and passing it the same
// value used when you instantiated the registerInFactory object.
// For example:
// base header:
// class Base { /* whatever (don't forget the virtual dtor! */ };
//
// base implementation:
// registerInFactory<Base, Base, std::string> registerBase("Base");
//
// derived header:
// class Derived : public Base { /* whatever */ };
//
// derived implementation:
// registerInFactory<Base, Derived, std::string> registerDer("Derived");
//
// code that instantiates the classes:
// std::auto_ptr<Base> newBase =
objectFactory<Base>::instance().create("Base");
// std::auto_ptr<Base> newDerived =
objectFactory<Base>::instance().create("Derived");
//
// New derivatives can be added without affecting the existing code.
#ifndef FACTORY_HEADER_DEFINED
#define FACTORY_HEADER_DEFINED
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;
//#pragma warning(disable: 4275)
//#pragma warning(disable: 4786)
// Macro to simplify registration with the Object Factory and creation of a
Clone function
// To be used in the class declaration in the header file (.h) for the new
class
#define FACTORY_DECLARE_CLASS(_cNewClass) \
static registerInFactory<CBase,_cNewClass>regClass;\
virtual shared_ptr<CBase>Clone()\
{return shared_ptr<CBase>(new _cNewClass(*this));}
// Macro to simplify implementation of the registration function
// To be used in the class implementation (.cpp) file for the new class
#define FACTORY_REGISTER_CLASS(_cNewClass) \
registerInFactory<CBase, _cNewClass> _cNewClass::regClass(#_cNewClass);
// The abstract factory itself.
// Implemented using the Singleton pattern
template <class manufacturedObj>
class objectFactory
{
public:
// a BASE_CREATE_FN is a function that takes no parameters
// and returns a pointer to a manufactuedObj. Note that
// we use no parameters, but you could add them
// easily enough to allow overloaded ctors, e.g.:
typedef manufacturedObj* (*BASE_CREATE_FN)();
typedef manufacturedObj* (*BASE_CLONE_FN)(manufacturedObj*);
int iTest;
// FN_REGISTRY is the registry of all the BASE_CREATE_FN
// pointers registered. Functions are registered using the
// regCreateFn member function (see below).
typedef map<string, BASE_CREATE_FN> FN_REGISTRY;
FN_REGISTRY registry;
typedef map<string, BASE_CLONE_FN> FN_CLONE_REGISTRY;
FN_CLONE_REGISTRY CloneRegistry;
// Singleton implementation - private ctor & copying, with
// no implementation on the copying.
objectFactory();
objectFactory(const objectFactory&); // Not implemented
objectFactory &operator=(const objectFactory&); // Not implemented
public:
// Singleton access.
static objectFactory &instance();
// Method to register the class ID key, and a pointer to
// the function that creates the class.
void regCreateFn(const string & strClassID, BASE_CREATE_FN);
// Method to register the class ID key, and a pointer to
// the function that clones
void regCloneFn(const string & strClassID, BASE_CLONE_FN);
// Create a new class of the type specified by className.
// manufacturedObj* manufacture(const std::string & className) const;
shared_ptr<manufacturedObj> manufacture(const std::string & className)
const;
shared_ptr<manufacturedObj> clone(shared_ptr<manufacturedObj> pToClone)
const;
// Create a new class of the type specified by className.
shared_ptr<manufacturedObj> assemble(list<string> &is,
list<string>::const_iterator& i) const;
};
////////////////////////////////////////////////////////////////////////
// Implementation details.
template <class manufacturedObj>
objectFactory<manufacturedObj>:bjectFactory()
{
cout << "Constructor: objectFactory for " << typeid(manufacturedObj).name()
<< endl;
}
template <class manufacturedObj>
objectFactory<manufacturedObj> & objectFactory<manufacturedObj>::instance()
{
// Note that this is not thread-safe!
static objectFactory theInstance;
return theInstance;
}
// Register the creation function. This simply associates the classIDKey
// with the function used to create the class. The return value is a dummy
// value, which is used to allow static initialization of the registry.
// See example implementations in base.cpp and derived.cpp
template <class manufacturedObj>
void objectFactory<manufacturedObj>::regCreateFn(const string & strClassID,
BASE_CREATE_FN func)
{
cout << "Registering create function for \"" << strClassID << "\"" << endl;
instance().registry[strClassID] = func;
cout << "Registry size = " << instance().registry.size() << "(" <<
&(instance().registry) << ")" << endl;
}
template <class manufacturedObj>
void objectFactory<manufacturedObj>::regCloneFn(const string & strClassID,
BASE_CLONE_FN func)
{
cout << "Registering clone function for \"" << strClassID << "\"" << endl;
instance().CloneRegistry[strClassID]=func;
}
template <class manufacturedObj>
shared_ptr<manufacturedObj>
objectFactory<manufacturedObj>::manufacture(const std::string & className)
const
{
cout << "Registry size = " << instance().registry.size() << "(" <<
&(instance().registry) << ")" << endl;
shared_ptr<manufacturedObj> manufactured;
cout << "Contents of Object Factory warehouse:" << endl;
typename FN_REGISTRY::const_iterator regIter = instance().registry.begin();
while (regIter != instance().registry.end())
cout << regIter->first << endl;
cout << endl;
typename FN_REGISTRY::const_iterator regEntry =
instance().registry.find(className);
cout << "Trying to manufacture \"" << className << "\"" << endl;
cout << "Object Factory " << &(instance().registry) << ": " <<
instance().registry.size() << " items" << endl;
if (regEntry != instance().registry.end())
manufactured.reset((*regEntry).second());
else
cout << "objectFactory: Don't know how to manufacture that object
type.\nEnsure that FACTORY_REGISTER_CLASS is used." << endl;
return manufactured;
}
// Clone an object using the class name of the cloned object
template <class manufacturedObj>
shared_ptr<manufacturedObj>
objectFactory<manufacturedObj>::clone(shared_ptr<manufacturedObj> pToClone)
const
{
cout << "clone(shared_ptr<manufacturedObj> pToClone) const" << endl;
shared_ptr<manufacturedObj> manufactured;
typename FN_CLONE_REGISTRY::const_iterator
regEntry=CloneRegistry.find(pToClone->ClassName());
if (regEntry != CloneRegistry.end())
manufactured =
shared_ptr<manufacturedObj>((*regEntry).second(pToClone.get()));
else
cout << "objectFactory: Don't know how to clone that object type.\nEnsure
that FACTORY_REGISTER_CLASS is used." << endl;
return manufactured;
}
// Assemble a new manufacturedObj using the list of string tokens and
iterator supplied
template <class manufacturedObj>
shared_ptr<manufacturedObj>
objectFactory<manufacturedObj>::assemble(list<std::string> &is,
list<string>::const_iterator& i) const
{
cout << "assemble" << endl;
string strObjType, strObjName;
list<string>::const_iterator start = i;
while ((i != is.end()) && ((*i).find("XSIL") == string::npos)) i++;
// Read back the object name, if it is present
while ((i != is.end()) && ((*i).find("Type") == string::npos)) i++;
while ((i != is.end()) && ((*i).find("=") == string::npos)) i++;
i++; strObjType = *i;
shared_ptr<manufacturedObj> ret;
typename FN_REGISTRY::const_iterator regEntry=registry.find(strObjType);
if (regEntry != registry.end())
ret.reset((*regEntry).second());
i = start;
ret->XML_Read(is, i);
return ret;
}
// ************************************************************
// Helper template to make registration painless and simple
// ************************************************************
template <class ancestorType,
class manufacturedObj>
class registerInFactory
{
public:
static ancestorType* createInstance()
{
cout << "createInstance()" << endl;
return (ancestorType*)(new manufacturedObj);
}
static ancestorType* cloneInstance(ancestorType * pObjToClone)
{
cout << "cloneInstance(ancestorType * pObjToClone)" << endl;
manufacturedObj * pDerivedToClone = new manufacturedObj;
*pDerivedToClone = *((manufacturedObj*)pObjToClone);
// pDerivedToClone = (manufacturedObj*) pObjToClone;
// cout << "Cloning " << pObjToClone->GetID() << endl;
// return (ancestorType*)(new
manufacturedObj(*((manufacturedObj*)pObjToClone)));
return (ancestorType*)pDerivedToClone;
}
registerInFactory(const string id)
{
m_strClassName.assign(id);
objectFactory<ancestorType>::instance().regCreateFn(m_strClassName,
createInstance);
objectFactory<ancestorType>::instance().regCloneFn(m_strClassName,
cloneInstance);
cout << "registerInFactory: \"" << m_strClassName << "\"" << endl;
}
protected:
string m_strClassName;
};
#endif
I have code for an object factory, heavily based on an article by Jim Hyslop
(although I've made minor modifications). The factory was working fine using
g++, but since switching to the Intel compiler it has stopped working. I
think the singleton pattern static instance thing may be at the root of the
problem, but I'm not sure. I had to add calls to instance() in regCreateFn,
which gets the behaviour more in line with what I was expecting during
static initialization (the objects all register with the same registry). I
have tried playing with the MS compatibility options of the Intel compiler,
with no success.
The problem occurs when I make a call to manufacture a given object: a
totally different instance of the factory and registry are used (I have
checked this by printing out pointers).
A typical call to the manufacture method would be:
shared_ptr<CAngle3D> newB = boost::shared_polymorphic_cast<CAngle3D>
(objectFactory<CBase>::instance().manufacture("CAngle3D"));
This fails, since the objectFactory<CBase>::instance() returns a valid
factory, but one with no items in the map of create functions (i.e. it is a
different one to that used when registering the create functions in the
static initalizers).
In this example, the first section of the header for CAngle3D is as follows:
class CAngle3D : public CBase
{
public:
// Tell the Object Factory about this class
//FACTORY_DECLARE_CLASS(CAngle3D
static registerInFactory<CBase, CAngle3D> regClass;
and the following is placed into the cpp for CAngle3D:
// Register class with Object Factory
//FACTORY_REGISTER_CLASS(CAngle3D)
registerInFactory<CBase, CAngle3D> CAngle3D::regClass("CAngle3D");
The complete CFactory.h listing is pasted at the end of this email. You will
notice that there is a large amount of debugging info being output.
The output of my program, when it starts up, is as follows: (Notice
especially the memory addresses, that change when the program tries to
manufacture a CAngle3D object)
$ ./TestMathCore
Constructor: objectFactory for class CBase
Registering create function for "CAngle3D"
Registry size = 1(0046FBD0)
Registering clone function for "CAngle3D"
registerInFactory: "CAngle3D"
Constructor: objectFactory for class CBase
Registering create function for "CFrequency"
Registry size = 2(0046FBD0)
Registering clone function for "CFrequency"
registerInFactory: "CFrequency"
Constructor: objectFactory for class CBase
Registering create function for "CList"
Registry size = 3(0046FBD0)
Registering clone function for "CList"
registerInFactory: "CList"
Constructor: objectFactory for class CBase
Registering create function for "CSortableList"
Registry size = 4(0046FBD0)
Registering clone function for "CSortableList"
registerInFactory: "CSortableList"
Constructor: objectFactory for class CBase
Registering create function for "CCollection"
Registry size = 5(0046FBD0)
Registering clone function for "CCollection"
registerInFactory: "CCollection"
Constructor: objectFactory for class CBase
Registering create function for "CAngle"
Registry size = 6(0046FBD0)
Registering clone function for "CAngle"
registerInFactory: "CAngle"
Min resolution = 1, Max resolution = 1000000
Timer setting successful.
The system clock interval is 10 ms.
Adjustment disabled = 1
MathCore Test App
-----------------
CAngle3D
Constructor: objectFactory for class CBase
Registry size = 0(0046FB04)
Contents of Object Factory warehouse:
Trying to manufacture "CAngle3D"
Object Factory 0046FB04: 0 items
objectFactory: Don't know how to manufacture that object type.
Ensure that FACTORY_REGISTER_CLASS is used.
I would *really* appreciate some help! Sorry for the hugely long post . . .
Ryan
// CFactory.h
// object abstract factory template.
// Copyright 2001, Jim Hyslop.
// This file may be freely used, modified and distributed, provided that
// the accompanying copyright notice remains intact.
//
// The object abstract factory template is an implementation of the
// Abstract Class Factory pattern, as a template (see "Design Patterns:
// Elements of Reusable Object-Oriented Software", E. Gamma, R. Helm,
// R. Johnson, J. Vlissides, Addison Wesley [1995] )
//
// To use the template, you need to provide a base class and (optionally)
// a key class. The base class must provide a unique identifier
//
// The key class must be able to be used as a key in a std::map, i.e. it
must
// - implement copy and assignment semantics
// - provide bool operator< () const;
// Default is std::string.
//
// Steps to using the factory:
// 1 - Create the base class and its derivatives
// 2 - Register each class in the factory by instantiating a
// registerInFactory<> template class - do this in one file only (the
// class implementation file is the perfect place for this)
// 3 - create the object by calling create() and passing it the same
// value used when you instantiated the registerInFactory object.
// For example:
// base header:
// class Base { /* whatever (don't forget the virtual dtor! */ };
//
// base implementation:
// registerInFactory<Base, Base, std::string> registerBase("Base");
//
// derived header:
// class Derived : public Base { /* whatever */ };
//
// derived implementation:
// registerInFactory<Base, Derived, std::string> registerDer("Derived");
//
// code that instantiates the classes:
// std::auto_ptr<Base> newBase =
objectFactory<Base>::instance().create("Base");
// std::auto_ptr<Base> newDerived =
objectFactory<Base>::instance().create("Derived");
//
// New derivatives can be added without affecting the existing code.
#ifndef FACTORY_HEADER_DEFINED
#define FACTORY_HEADER_DEFINED
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;
//#pragma warning(disable: 4275)
//#pragma warning(disable: 4786)
// Macro to simplify registration with the Object Factory and creation of a
Clone function
// To be used in the class declaration in the header file (.h) for the new
class
#define FACTORY_DECLARE_CLASS(_cNewClass) \
static registerInFactory<CBase,_cNewClass>regClass;\
virtual shared_ptr<CBase>Clone()\
{return shared_ptr<CBase>(new _cNewClass(*this));}
// Macro to simplify implementation of the registration function
// To be used in the class implementation (.cpp) file for the new class
#define FACTORY_REGISTER_CLASS(_cNewClass) \
registerInFactory<CBase, _cNewClass> _cNewClass::regClass(#_cNewClass);
// The abstract factory itself.
// Implemented using the Singleton pattern
template <class manufacturedObj>
class objectFactory
{
public:
// a BASE_CREATE_FN is a function that takes no parameters
// and returns a pointer to a manufactuedObj. Note that
// we use no parameters, but you could add them
// easily enough to allow overloaded ctors, e.g.:
typedef manufacturedObj* (*BASE_CREATE_FN)();
typedef manufacturedObj* (*BASE_CLONE_FN)(manufacturedObj*);
int iTest;
// FN_REGISTRY is the registry of all the BASE_CREATE_FN
// pointers registered. Functions are registered using the
// regCreateFn member function (see below).
typedef map<string, BASE_CREATE_FN> FN_REGISTRY;
FN_REGISTRY registry;
typedef map<string, BASE_CLONE_FN> FN_CLONE_REGISTRY;
FN_CLONE_REGISTRY CloneRegistry;
// Singleton implementation - private ctor & copying, with
// no implementation on the copying.
objectFactory();
objectFactory(const objectFactory&); // Not implemented
objectFactory &operator=(const objectFactory&); // Not implemented
public:
// Singleton access.
static objectFactory &instance();
// Method to register the class ID key, and a pointer to
// the function that creates the class.
void regCreateFn(const string & strClassID, BASE_CREATE_FN);
// Method to register the class ID key, and a pointer to
// the function that clones
void regCloneFn(const string & strClassID, BASE_CLONE_FN);
// Create a new class of the type specified by className.
// manufacturedObj* manufacture(const std::string & className) const;
shared_ptr<manufacturedObj> manufacture(const std::string & className)
const;
shared_ptr<manufacturedObj> clone(shared_ptr<manufacturedObj> pToClone)
const;
// Create a new class of the type specified by className.
shared_ptr<manufacturedObj> assemble(list<string> &is,
list<string>::const_iterator& i) const;
};
////////////////////////////////////////////////////////////////////////
// Implementation details.
template <class manufacturedObj>
objectFactory<manufacturedObj>:bjectFactory()
{
cout << "Constructor: objectFactory for " << typeid(manufacturedObj).name()
<< endl;
}
template <class manufacturedObj>
objectFactory<manufacturedObj> & objectFactory<manufacturedObj>::instance()
{
// Note that this is not thread-safe!
static objectFactory theInstance;
return theInstance;
}
// Register the creation function. This simply associates the classIDKey
// with the function used to create the class. The return value is a dummy
// value, which is used to allow static initialization of the registry.
// See example implementations in base.cpp and derived.cpp
template <class manufacturedObj>
void objectFactory<manufacturedObj>::regCreateFn(const string & strClassID,
BASE_CREATE_FN func)
{
cout << "Registering create function for \"" << strClassID << "\"" << endl;
instance().registry[strClassID] = func;
cout << "Registry size = " << instance().registry.size() << "(" <<
&(instance().registry) << ")" << endl;
}
template <class manufacturedObj>
void objectFactory<manufacturedObj>::regCloneFn(const string & strClassID,
BASE_CLONE_FN func)
{
cout << "Registering clone function for \"" << strClassID << "\"" << endl;
instance().CloneRegistry[strClassID]=func;
}
template <class manufacturedObj>
shared_ptr<manufacturedObj>
objectFactory<manufacturedObj>::manufacture(const std::string & className)
const
{
cout << "Registry size = " << instance().registry.size() << "(" <<
&(instance().registry) << ")" << endl;
shared_ptr<manufacturedObj> manufactured;
cout << "Contents of Object Factory warehouse:" << endl;
typename FN_REGISTRY::const_iterator regIter = instance().registry.begin();
while (regIter != instance().registry.end())
cout << regIter->first << endl;
cout << endl;
typename FN_REGISTRY::const_iterator regEntry =
instance().registry.find(className);
cout << "Trying to manufacture \"" << className << "\"" << endl;
cout << "Object Factory " << &(instance().registry) << ": " <<
instance().registry.size() << " items" << endl;
if (regEntry != instance().registry.end())
manufactured.reset((*regEntry).second());
else
cout << "objectFactory: Don't know how to manufacture that object
type.\nEnsure that FACTORY_REGISTER_CLASS is used." << endl;
return manufactured;
}
// Clone an object using the class name of the cloned object
template <class manufacturedObj>
shared_ptr<manufacturedObj>
objectFactory<manufacturedObj>::clone(shared_ptr<manufacturedObj> pToClone)
const
{
cout << "clone(shared_ptr<manufacturedObj> pToClone) const" << endl;
shared_ptr<manufacturedObj> manufactured;
typename FN_CLONE_REGISTRY::const_iterator
regEntry=CloneRegistry.find(pToClone->ClassName());
if (regEntry != CloneRegistry.end())
manufactured =
shared_ptr<manufacturedObj>((*regEntry).second(pToClone.get()));
else
cout << "objectFactory: Don't know how to clone that object type.\nEnsure
that FACTORY_REGISTER_CLASS is used." << endl;
return manufactured;
}
// Assemble a new manufacturedObj using the list of string tokens and
iterator supplied
template <class manufacturedObj>
shared_ptr<manufacturedObj>
objectFactory<manufacturedObj>::assemble(list<std::string> &is,
list<string>::const_iterator& i) const
{
cout << "assemble" << endl;
string strObjType, strObjName;
list<string>::const_iterator start = i;
while ((i != is.end()) && ((*i).find("XSIL") == string::npos)) i++;
// Read back the object name, if it is present
while ((i != is.end()) && ((*i).find("Type") == string::npos)) i++;
while ((i != is.end()) && ((*i).find("=") == string::npos)) i++;
i++; strObjType = *i;
shared_ptr<manufacturedObj> ret;
typename FN_REGISTRY::const_iterator regEntry=registry.find(strObjType);
if (regEntry != registry.end())
ret.reset((*regEntry).second());
i = start;
ret->XML_Read(is, i);
return ret;
}
// ************************************************************
// Helper template to make registration painless and simple
// ************************************************************
template <class ancestorType,
class manufacturedObj>
class registerInFactory
{
public:
static ancestorType* createInstance()
{
cout << "createInstance()" << endl;
return (ancestorType*)(new manufacturedObj);
}
static ancestorType* cloneInstance(ancestorType * pObjToClone)
{
cout << "cloneInstance(ancestorType * pObjToClone)" << endl;
manufacturedObj * pDerivedToClone = new manufacturedObj;
*pDerivedToClone = *((manufacturedObj*)pObjToClone);
// pDerivedToClone = (manufacturedObj*) pObjToClone;
// cout << "Cloning " << pObjToClone->GetID() << endl;
// return (ancestorType*)(new
manufacturedObj(*((manufacturedObj*)pObjToClone)));
return (ancestorType*)pDerivedToClone;
}
registerInFactory(const string id)
{
m_strClassName.assign(id);
objectFactory<ancestorType>::instance().regCreateFn(m_strClassName,
createInstance);
objectFactory<ancestorType>::instance().regCloneFn(m_strClassName,
cloneInstance);
cout << "registerInFactory: \"" << m_strClassName << "\"" << endl;
}
protected:
string m_strClassName;
};
#endif