How to create an array of classes in c++? - c++

Code:
struct Base { ... };
struct A : public Base { ... };
struct B : public Base { ... };
struct C : public Base { ... };
Is it possible to create an array, that holds that types of struct?
sample/expected result:
Type inheritedTypesOfStruct[3] = {A, B, C};
The purpose of this is that I later want to create an object with a random class retrieved from the array.

You could create an array of functions, each of which returns a base pointer(or smart pointer) that each point to objects of your various derived classes. e.g.
typedef std::unique_ptr<Base> base_ptr;
template<typename Derived>
base_ptr CreateObject()
{
return base_ptr(new Derived);
}
int main()
{
std::function<base_ptr(void)> f[3] = {
CreateObject<A>, CreateObject<B>, CreateObject<C>
};
base_ptr arr[10];
for (int i=0; i<10; ++i)
arr[i] = f[rand()%3]();
}
Here it is in action: http://ideone.com/dg4uq

If your compiler supports RTTI, you can do something like:
const type_info *inheritedTypesOfStruct[3] = {
&typeid(A), &typeid(B), &typeid(C)
};
However, you won't be able to instantiate a class using only its type_info. The factory pattern might be a better answer to your root problem.
Update: Since type_info instances cannot be copied (their copy constructor and assignment operator are private), and arrays of references are illegal, constant pointers have to be used in the example above.

#include <cstdlib>
#include <ctime>
#include <iostream>
#include <map>
#include <vector>
#include <memory>
using namespace std;
// interface
class Base
{
public:
virtual ~Base() { }
virtual int getClassId() = 0;
};
// class A relizes interface Base, has ID == 1 (is used in automatic registration to factory)
class A : public Base
{
public:
const static int ID = 1;
static Base* CreateInstance()
{
return new A();
}
virtual int getClassId()
{
return ID;
}
virtual ~A() { }
};
// class B relizes interface Base, has ID == 2 (is used in automatic registration to factory)
class B : public Base
{
public:
const static int ID = 2;
static Base* CreateInstance()
{
return new B();
}
virtual int getClassId()
{
return ID;
}
virtual ~B() { }
};
// this is the objects factory, with registration only (unregister s not allowed)
class ObjectFactory
{
ObjectFactory() { }
ObjectFactory(ObjectFactory&) { }
public:
virtual ~ObjectFactory() { }
static ObjectFactory& instance()
{
static ObjectFactory objectFactory;
return objectFactory;
}
typedef Base* (*Creator) ();
void registerCreator(int id, Creator creator)
{
registry[id] = creator;
}
Base* CreateById(int id)
{
return registry[id]();
}
private:
map<int, Creator> registry;
};
// this template class is used for automatic registration of object's creators
template <class T>
struct RegisterToFactory
{
RegisterToFactory(ObjectFactory& factory)
{
factory.registerCreator(T::ID, &T::CreateInstance);
}
};
namespace
{
// automaticaly register creators for each class
RegisterToFactory<A> autoregisterACreator(ObjectFactory::instance());
RegisterToFactory<B> autoregisterBCreator(ObjectFactory::instance());
}
// lets this this solution
int main(int argc, char *argv[])
{
vector<int> ids;
ids.push_back(static_cast<int>(A::ID));
ids.push_back(static_cast<int>(B::ID));
srand(time(0));
for (int i = 0; i < 20; ++i)
{
int randomClasssId = ids[rand() % ids.size()];
auto_ptr<Base> testObject(ObjectFactory::instance().CreateById(randomClasssId));
cout << "Object of classId = " << testObject->getClassId() << " has been produced by factory." << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}

I don't get the question. Are you asking for an array that can hold different type of instances at the same time? That is possible using polymorphism, of course. Or are you trying to get an array of types (like reflection)? That would be possible using RTTI or Qt type information (as an example), but I never did that.

You can take a look here: http://www.java2s.com/Code/Cpp/Class/Objectarraypolymorphism.htm
on how to use Polymorphism in C++.

Related

Best way of creating polymorphic C++ objects with types based on a string?

I want to create objects with polymorphic types based on a string I read from some config text file. A naive simple solution to this is to assign a string to each possible type and then compare the config string in an else-if chain to all the defined types. Something like:
class Base
{
virtual std::string GetStringType() = 0;
};
class Derived1 : public Base
{
std::string GetStringType() override { return "Derived1"; }
};
class Derived2 : public Base
{
std::string GetStringType() override { return "Derived2"; }
};
// etc ...
void main(int argc, char *argv[])
{
std::unique_ptr<Base> ptr;
auto derived1 = std::make_unique<Derived1>();
auto derived2 = std::make_unique<Derived2>();
// etc ...
std::string stringType(argv[1]);
if (stringType == derived1->GetStringType())
ptr = std::make_unique<decltype(derived1)>();
else if (stringType == derived2->GetStringType())
ptr = std::make_unique<decltype(derived2)>();
// etc ...
}
However, with this approach, each time a new derived class is added, a new else-if branch needs to be manually added, and I am trying to avoid that. Is there a better, more automatic approach to this?
Also, in an ideal scenario, when a new derived class is defined somewhere (just defined, not instantiated), I would like to check against it automatically also. Is this somehow possible? I'd be happy for any solution that works, macros included.
A simple map-based factory can do the trick:
#include <map>
#include <functional>
#include <string>
#include <memory>
class Base
{
public:
virtual ~Base() = default;
static std::unique_ptr<Base> create(const std::string& name) {
return factories_.at(name)();
}
template<typename T>
static void registerDerived() {
static_assert(std::is_base_of_v<Base, T>);
factories_[T::GetStringType()] = std::make_unique<T>;
}
private:
static std::map<std::string, std::function<std::unique_ptr<Base>()>> factories_;
};
std::map<std::string, std::function<std::unique_ptr<Base>()>> Base::factories_;
class Derived1 : public Base
{
public:
static std::string GetStringType() { return "Derived1"; }
};
class Derived2 : public Base
{
public:
static std::string GetStringType() { return "Derived2"; }
};
int main(int argc, char *argv[]) {
Base::registerDerived<Derived1>();
Base::registerDerived<Derived2>();
// etc...
std::unique_ptr<Base> ptr = Base::create(argv[1]);
// ...
}
This is an example based on unordered_map, with an explicit class factory.
Decoupling the creation of the instances completely from the base class.
(Separation of concerns)
#include <type_traits>
#include <string>
#include <functional>
#include <iostream>
#include <memory>
#include <unordered_map>
#include <stdexcept>
#include <sstream>
//-------------------------------------------------------------------------------------------------
class Base
{
public:
virtual void Hello() = 0;
};
class Class1 : public Base
{
public:
void Hello() override
{
std::cout << "Class1\n";
}
};
class Class2 : public Base
{
public:
void Hello() override
{
std::cout << "Class2\n";
}
};
//-------------------------------------------------------------------------------------------------
class ClassFactory final
{
public:
// For each class registered at a function to the map
// that will create a unique_ptr to a new instance of that class
template<typename class_t>
void Register(const std::string& string)
{
static_assert(std::is_base_of_v<Base, class_t>, "You can only register classes derived from Base");
// create_function is a lambda
auto create_function = [] { return std::make_unique<class_t>(); };
// add the function to the map, with the string as key
create_function_map.insert({ string,create_function });
}
std::unique_ptr<Base> Create(const std::string& string)
{
// if nothing is found for the string then throw an exception
if (create_function_map.find(string) == create_function_map.end())
{
std::ostringstream os;
os << "No class registered for string : " << string;
throw std::invalid_argument(os.str());
}
// otherwise call the function that will make an instance of the
// derived class
auto create_function = create_function_map.at(string);
return create_function();
}
static ClassFactory& Instance()
{
static ClassFactory instance;
return instance;
}
private:
ClassFactory() = default;
~ClassFactory() = default;
// use unordered_map it has lookup complexity of O(1)
// std::map has a lookup complexity of O(n log(n))
std::unordered_map<std::string, std::function<std::unique_ptr<Base>()>> create_function_map;
};
//-------------------------------------------------------------------------------------------------
int main()
{
// For each new class register a name, this is the only code
// you need to expand to add new classes
// factory is a singleton so you can reuse it throughout your code
// without having to pass it around.
auto& factory = ClassFactory::Instance();
factory.Register<Class1>("Class1");
factory.Register<Class2>("Class2");
// create an instance of an object of type Class1.
auto object1 = factory.Create("Class1");
object1->Hello();
// create an instance of an object of type Class2.
auto object2 = factory.Create("Class2");
object2->Hello();
return 0;
}

How can one design a base class, so it knows about all the "derived" classes, at run time?

Normally, if you know all the types you intend to create before hand, you can just do something like this:
typedef enum{
BASE_CREATURE_TYPE = 0,
ANIMAL_CREATURE_TYPE,
...
}CREATURE_TYPES
But this becomes tedious, because each time you create a new class, you need to update the enum. Also, the CREATURE_TYPES is still just items in an enum - how to tie to an actual class ?
I was wondering if there was some way, I could just write the classes, and at run time, without actually instantiating an object, create a set containing all the types.
Is this possible in C++? In Java there is something called "static blocks", which are executed when the class is loaded by the JVM.
EDIT: This question is not about static blocks - It is just an example - I am wondering if there is some way, that I can execute a method or block of code so I know what classes exist at runtime, without actually creating an object
EDIT: I meant set of all types, not "maps", so I can create an object of each type, without having to maintain a list.
EDIT: The reason I want this, is because I am trying to create a function that can call methods on all derived classes that are part of the application. For example, say I have several classes which all derive from class Foo, and have a balls():
Foo{
balls();
}
Boo : public Foo{
balls();
}
Coo: public Foo{
balls():
}
At run time, I would like to know about all the derived classes so I can call:
DerivedClass:balls();
EDIT: Note, that I do not need to know about all the members of each derived class, I just want to know what all the derived classes are, so I can call balls(), on each of them.
EDIT: This question is similar: How to automatically register a class on creation
But unfortunately, he is storing an std::string(). How does one refer to the actual class ?
EDIT: In Smeehey's answer below, in the main method, how would I actually create an instance of each class, and call both static and non-static methods ?
You could create a static registry for all your classes, and use a couple of helper macros to register new types within it. Below is a basic working demonstration, which creates 2 derived classes from Base. To add new classes you just use the two macros shown - one inside and one outside the class. Note: the example is very bare-bones and doesn't concern itself with things like checking for duplicates or other error conditions to maximise clarity.
class BaseClass
{
};
class Registry
{
public:
static void registerClass(const std::string& name, BaseClass* prototype)
{
registry[name] = prototype;
}
static const std::map<std::string, BaseClass*>& getRegistry() { return registry; };
private:
static std::map<std::string, BaseClass*> registry;
};
std::map<std::string, BaseClass*> Registry::registry;
#define REGISTER_CLASS(ClassType) static int initProtoType() { static ClassType proto; Registry::registerClass(std::string(#ClassType), &proto); return 0; } static const int regToken;
#define DEFINE_REG_CLASS(ClassType) const int ClassType::regToken = ClassType::initProtoType();
class Instance : public BaseClass
{
REGISTER_CLASS(Instance)
};
DEFINE_REG_CLASS(Instance)
class OtherInstance : public BaseClass
{
REGISTER_CLASS(OtherInstance)
};
DEFINE_REG_CLASS(OtherInstance)
int main()
{
for(auto entry : Registry::getRegistry())
{
std::cout << entry.first << std::endl;
}
return 0;
}
The above registers prototypes of the derived classes, which could be used for copy-constructing other instances for example. As an alternative, requested by the OP, you can have a system where factory methods are registered instead of prototypes. This allows you to create instances using a constructor with any particular signature, rather than the copy constructor:
class BaseClass
{
};
class Registry
{
public:
using factoryMethod = BaseClass* (*)(int a, int b, int c);
static void registerClass(const std::string& name, factoryMethod meth)
{
registry[name] = meth;
}
static BaseClass* createInstance(const std::string& type, int a, int b, int c)
{
return registry[type](a, b, c);
}
static const std::map<std::string, factoryMethod>& getRegistry() { return registry; };
private:
static std::map<std::string, factoryMethod> registry;
};
std::map<std::string, Registry::factoryMethod> Registry::registry;
#define REGISTER_CLASS(ClassType) static BaseClass* createInstance(int a, int b, int c) \
{ \
return new ClassType(a,b,c); \
} \
static int initRegistry() \
{ \
Registry::registerClass( \
std::string(#ClassType), \
ClassType::createInstance); \
return 0; \
} \
static const int regToken; \
#define DEFINE_REG_CLASS(ClassType) const int ClassType::regToken = ClassType::initRegistry();
class Instance : public BaseClass
{
Instance(int a, int b, int c){}
REGISTER_CLASS(Instance)
};
DEFINE_REG_CLASS(Instance)
class OtherInstance : public BaseClass
{
OtherInstance(int a, int b, int c){}
REGISTER_CLASS(OtherInstance)
};
DEFINE_REG_CLASS(OtherInstance)
int main()
{
std::vector<BaseClass*> objects;
for(auto entry : Registry::getRegistry())
{
std::cout << entry.first << std::endl;
objects.push_back(Registry::createInstance(entry.first, 1, 2, 3));
}
return 0;
}
Use the CRTP design with interface for common "ancestor":
#include <vector>
#include <iostream>
/* Base */
struct IBase
{
virtual void balls() = 0;
virtual IBase *clone() const = 0;
private:
static std::vector<IBase const *> _Derived;
public:
static void
create_all(void)
{
std::cout << "size: " << _Derived.size() << "\n";
for (IBase const *a : _Derived)
{
IBase *new_object(a->clone());
(void)new_object; // do something with it
}
}
};
std::vector<IBase const *> IBase::_Derived;
/* Template for CRTP */
template<class DERIVED>
class Base : public IBase
{
static bool created;
static Base const *_model;
public:
Base(void)
{
if (not created)
{
_Derived.push_back(this);
created = true;
}
}
};
template<class DERIVED>
bool Base<DERIVED>::created = false;
template<class DERIVED>
Base<DERIVED> const *Base<DERIVED>::_model = new DERIVED;
/* Specialized classes */
struct Foo1 : public Base<Foo1>
{
IBase *clone() const
{
std::cout << "new Foo1\n";
return new Foo1(*this);
}
void balls() {}
};
struct Foo2 : public Base<Foo2>
{
IBase *clone() const
{
std::cout << "new Foo2\n";
return new Foo2(*this);
}
void balls() {}
};
int main(void)
{
Foo1 a;
IBase::create_all();
}
I tried this solution, but I do not know why the static Base const *_model; is not created when running the program.
You may use a global factory holding functions able to create objects (unique_ptr's) of derived classes:
#include <memory>
#include <unordered_map>
#include <typeinfo>
#include <typeindex>
// Factory
// =======
template <typename Base>
class Factory
{
public:
template <typename Derived>
struct Initializer {
Initializer() {
Factory::instance().register_producer<Derived>();
}
};
typedef std::function<std::unique_ptr<Base>()> producer_function;
typedef std::unordered_map<std::type_index, producer_function> producer_functions;
static Factory& instance();
void register_producer(const std::type_info& type, producer_function producer) {
m_producers[std::type_index(type)] = std::move(producer);
}
template <typename Derived>
void register_producer() {
register_producer(
typeid(Derived),
[] () { return std::make_unique<Derived>(); });
}
producer_function producer(const std::type_info& type) const {
auto kv = m_producers.find(std::type_index(type));
if(kv != m_producers.end())
return kv->second;
return producer_function();
}
const producer_functions producers() const { return m_producers; }
private:
producer_functions m_producers;
};
template <typename Base>
Factory<Base>& Factory<Base>::instance() {
static Factory result;
return result;
}
// Test
// ====
#include <iostream>
class Base
{
public:
~Base() {}
virtual void print() = 0;
};
class A : public Base
{
public:
void print() override { std::cout << "A\n"; }
static void f() {}
};
Factory<Base>::Initializer<A> A_initializer;
class B : public Base
{
public:
void print() override { std::cout << "B\n"; }
};
Factory<Base>::Initializer<B> B_initializer;
class C {};
int main()
{
auto& factory = Factory<Base>::instance();
// unique_ptr
auto producerA = factory.producer(typeid(A));
if(producerA) {
auto ptrA = producerA();
ptrA->print();
}
// shared_ptr
auto producerB = factory.producer(typeid(B));
if(producerB) {
std::shared_ptr<Base> ptrB(producerB());
ptrB->print();
}
// missing
auto producerC = factory.producer(typeid(C));
if( ! producerC) {
std::cout << "No producer for C\n";
}
// unordered
for(const auto& kv : factory.producers()) {
kv.second()->print();
}
}
Note: The factory does not provide means of calling static member functions without object.

C++ call via pointer-to-member function in a derived class from the base class

I would like to pose the following design pattern to discussion. It implements a universal "getMany" method in the base class that uses a given get-method from the derived class to get many entities (here for simplification of explicit type int). This means that any derived class has to inform the "getMany" method which get-method to use. This is a case of calling a pointer-to-member function in a derived class from the base class.
What I would like to pose to discussion: what alternative, easier patterns to achieve the same can you think of?
Thank you!
P.S.: As noted above in a real case one would of course abstract the fixed type "int" to a template type T.
P.P.S.: predefining the get-methods as virtual methods in the base class did not seem a good option, since it would restrict the number of and naming of the get-methods.
#include <iostream>
#include <memory>
#include <algorithm>
#include <vector>
using namespace std;
// EXAMPLE FOR CALL VIA POINTER TO OVERLOADED METHOD IN DERIVED CLASS FROM BASE CLASS
class FooBase
{
public:
template<class PCLASS>
std::vector<int> getMany(int (PCLASS::*getEnt)(int) const, int n, const PCLASS *pClass) const
{
std::vector<int> e;
int i = 0;
e.resize(n);
for (std::vector<int>::iterator it = e.begin(); it!=e.end(); ++it) {
*it = (pClass->*getEnt)( i++ );
}
return e;
};
};
class Foo : public FooBase
{
public:
int Moo(int a) const
{
return a;
};
int Moo(char a) const
{
return (int)a;
};
std::vector<int> Moos(int n) const
{
int (Foo::*f)(int)const;
f = &Foo::Moo;
return getMany<Foo>(f, n, this);
};
};
int main(int argc, char **args)
{
Foo* myFoo = new Foo();
std::vector<int> res = myFoo->Moos(10);
for (std::vector<int>::iterator it = res.begin(); it!=res.end(); ++it) {
std::cout << *it;
}
return 1;
}
Here is an example using function objects.
class FooBase
{
public:
template< typename FunctorType >
std::vector<int> getMany(FunctorType const & functor, int n)
{
std::vector<int> e;
int i = 0;
e.resize(n);
for (std::vector<int>::iterator it = e.begin(); it!=e.end(); ++it) {
*it = functor( i++ );
}
}
};
With this, client code can call getMany using lambdas (c++11) or create their own function objects.
auto callMoo = [this] (char i) { return Moo(i); };
getMany(callMoo, n);
You can just use regular polymorphism here. Have an abstract method that you call via the this pointer from the base class method. A simplified example is:
class FooBase
{
public:
virtual void abstractCall() = 0; // pure virtual function, could make protected if you wanted
void baseMethod()
{
this->abstractCall(); // MUST use the this pointer, not a "." call
}
};
class FooDerived : public FooBase
{
public:
virtual void abstractCall()
{
cout << "my concrete call!" << endl;
}
};
void bar()
{
FooDerived test;
test.baseMethod();
}
I hope that gives you the basic idea.

Insert function pointer into map with polymorphic return type

I didn't know exactly how to title this question. I have a base class and two inheriting classes:
class Base {};
class Action : public Base {};
class Title : public Base {};
Now let's say I have two functions that return either Action * or Title *:
Action *getAction() { return new Action; }
Title *getTitle() { return new Title; }
Is there any way to put these two functions into a map? Like so:
int main()
{
std::map<std::string, Base *(*)()> myMap;
myMap["action"] = getAction;
myMap["title"] = getTitle;
return 0;
}
Right now I'm getting an error:
invalid conversion from `Action* (*)()' to `Base* (*)()'
I could change the signature of the functions to always return the base class, and then it would work, but I'm wondering if there is another way to get around this.
If you use:
Base *getAction() { return static_cast<Base *>(new Action); }
Base *getTitle() { return static_cast<Base *>(new Title); }
then you will not get this error.
std::function is a polymorphic function pointer wrapper provided by the STL.
Of course, using templates, you could write your own function wrapper that stores a target, passes forward arguments and does conversion. This has already been done though, and you should seriously consider carefully before you decide to roll your own. Unless you enjoy reinventing wheels or have very special requirements.
As a proof of concept I have this code:
#include <iostream>
#include <map>
#include <functional>
struct A
{
virtual void f() = 0;
};
struct B : public A
{
void f() { std::cout << "B::f\n"; }
};
struct C : public A
{
void f() { std::cout << "C::f\n"; }
};
B* getB() { return new B; }
C* getC() { return new C; }
int main()
{
std::map<std::string, std::function<A*()>> m;
m["b"] = getB;
m["c"] = getC;
m["b"]()->f();
m["c"]()->f();
}
It leaks memory, but it works.

Can you create a std::map of inherited classes?

I'm wondering if it's possible to create a map of pointers of inherited classes. Here's an example of what I'm trying to do:
#include <string>
#include <map>
using namespace std;
class BaseClass
{
string s;
};
class Derived1 : public BaseClass
{
int i;
};
class Derived2 : public Derived1
{
float f;
};
// Here's what I was trying, but isn't working
template<class myClass>
map<string, myClass>m;
int main()
{
// Add BaseClasses, Derived1's, and/or Derived2's to m here
return 0;
}
The errors I get are:
main.cpp(23): error C2133: 'm' : unknown size
main.cpp(23): error C2998: 'std::map<std::string,myClass>m' : cannot be a template definition
I get why I'm getting this error, but I'm wondering if it's possible to create a map that can hold different levels of inherited classes? If not, is it possible to create some sort of management system that can hold various class types? Or would I have to make different maps/vectors/arrays/etc. for each type of class?
Yes you can store inherited classes in map, but pointers to them, not objects themselves. Here's a short example (it lacks memory management on pointers)
#include <iostream>
#include <string>
#include <map>
#include <utility>
using namespace std;
class BaseClass
{
string s;
public:
BaseClass() { s = "BaseClass";}
virtual void print()
{
cout << s << std::endl;
}
};
class Derived1 : public BaseClass
{
int i;
public:
Derived1() { i = 10; }
void print()
{
cout << i << std::endl;
}
};
class Derived2 : public Derived1
{
float f;
public:
Derived2() { f = 4.3;}
void print()
{
cout << f << std::endl;
}
};
int main()
{
map<string, BaseClass*>m;
m.insert(make_pair("base", new BaseClass()));
m.insert(make_pair("d1", new Derived1()));
m.insert(make_pair("d2", new Derived2()));
m["base"]->print();
m["d1"]->print();
m["d2"]->print();
return 0;
}
First things first:
template<class myClas>
map<string, myClass> m;
This is not valid C++ and could only mean something like a template alias, but I believe, that is not what you are looking for.
Storing polymorphic objects in C++ is complicated by slicing (constructing a value of the base type from a value of a derived type). Dynamic polymorphism can only be handled through references or pointers. You could potentially use std::ref or boost::ref for situations in which the map will only be passed down the callstack, but this requires some care. Often, storing pointers to the base is the way to go: std::map<std::string, base*>. Managing deallocation yourself is rather tedious and either std::map<std::string, std::unique_ptr> or std::map<std::string, std::shared_ptr> are preferred, depending if you need shared semantics or not.
Basic example. Someone should replace this with something more meaningful.
#include <memory>
#include <string>
#include <map>
#include <iostream>
class animal
{
public:
virtual ~animal() {};
virtual void make_sound() const = 0;
};
class dog : public animal
{
public:
void make_sound() const { std::cout << "bark" << std::endl; }
};
class bird : public animal
{
public:
void make_sound() const { std::cout << "chirp" << std::endl; }
};
int main()
{
std::map<std::string, std::unique_ptr<animal>> m;
m.insert(std::make_pair("stupid_dog_name", new dog));
m.insert(std::make_pair("stupid_bird_name", new bird));
m["stupid_dog_name"]->make_sound();
return 0;
}
You may have template on classes and functions, but not on instances.
You should stick to the map to BaseClass*'es.
Below is the expansion of solution suggested by anton.
#include <iostream>
#include <string>
#include <map>
#include <utility>
using namespace std;
class BaseClass
{
string s;
public:
BaseClass() { s = "BaseClass";}
virtual ~ BaseClass(){}
virtual void print()=0;
};
class Derived1 : public BaseClass
{
int i;
public:
Derived1() { i = 10; }
void print()
{
cout << i << std::endl;
}
};
class Derived2 : public Derived1
{
float f;
public:
Derived2() { f = 4.3;}
void print()
{
cout << f << std::endl;
}
};
class factory
{
map<string, BaseClass*>m;
BaseClass* obj;
public:
factory()
{
obj=NULL;
}
BaseClass* FindType(string s);
void AddType(string s,BaseClass *obj);
void deleter();
~factory(){cout<<"deleting objects from map"<<endl;
deleter();
}
};
void factory :: AddType(string s,BaseClass* obj)
{
m.insert(make_pair(s,obj ));
}
void factory ::deleter ()
{
for (auto pObj = m.begin( );
pObj != m.end( ); ++pObj) {
delete pObj->second;
}
m.clear( );
}
BaseClass* factory::FindType(string s)
{
if(m.find(s)!=m.end())
{
return m[s];
}
return NULL;
}
int main()
{
BaseClass* obj;
factory fact_obj;
fact_obj.AddType("d1",new Derived1());
fact_obj.AddType("d2",new Derived2());
obj=fact_obj.FindType("d1");
if(obj!=NULL)
{
obj->print();
}
obj=fact_obj.FindType("d2");
if(obj!=NULL)
{
obj->print();
}
return 0;
}