V
Vladimir Jovic
Hello,
Following this :
http://www.codinginlondon.com/2009/05/cheap-ioc-in-native-c.html
I implemented an example of how I see IoC. This is just a naive attempt,
since the way the parameters are passed to the constructor is not very
good (at least in my opinion )
Can someone recommend a better way? A link to an example, or explanation
how it is done, would be best.
Here goes long example :
/// CODE
#include <string>
#include <map>
#include <iostream>
#include <typeinfo>
#include <cassert>
#include <memory>
class I
{
public:
I()
{
}
virtual ~I()
{
}
void foo()
{
doFoo();
}
private:
virtual void doFoo() = 0;
};
class A : public I
{
public:
A( const int v_) : I(),
v( v_ )
{
std::cout<<"A::A() v="<<v<<std::endl;
}
virtual ~A()
{
std::cout<<"A::~A()"<<std::endl;
}
static void setParams( const int nextParam )
{
newCreateParam = nextParam;
}
static I* create()
{
return new A( newCreateParam );
}
private:
virtual void doFoo()
{
std::cout<<"A::doFoo() v="<<v<<std::endl;
}
int v;
static int newCreateParam;
};
int A::newCreateParam=0;
class B : public I
{
public:
B() : I()
{
std::cout<<"B::B()"<<std::endl;
}
virtual ~B()
{
std::cout<<"B::~B()"<<std::endl;
}
static I* create()
{
return new B;
}
private:
virtual void doFoo()
{
std::cout<<"B::doFoo()"<<std::endl;
}
};
std::map< std::string, I* (*)() > GetCreator()
{
std::map< std::string, I* (*)() > m;
m[ typeid(A).name() ] = &A::create;
m[ typeid(B).name() ] = &B::create;
return m;
}
const std::map< std::string, I* (*)() > creator = GetCreator();
I* CreateObj( const std::string whichOne )
{
std::cout<<"Creating new object of type = " << whichOne << std::endl;
for ( std::map< std::string, I* (*)() >::const_iterator it =
creator.begin(); creator.end() != it; ++ it )
{
if ( std::string::npos != it->first.find( whichOne ) )
{
I* (*func)() = it->second;
return func();
}
}
std::cout<<"The creator for the class " << whichOne << " not
found." << std::endl;
return NULL;
}
int main()
{
A::setParams( 55 );
std::auto_ptr< I > newObj1( CreateObj( "B" ) );
std::auto_ptr< I > newObj2( CreateObj( "A" ) );
std::auto_ptr< I > newObj3( CreateObj( "C" ) );
if ( NULL != newObj1.get() )
{
newObj1->foo();
}
if ( NULL != newObj2.get() )
{
newObj2->foo();
}
if ( NULL != newObj3.get() )
{
newObj3->foo();
}
}
/// END OF CODE
Following this :
http://www.codinginlondon.com/2009/05/cheap-ioc-in-native-c.html
I implemented an example of how I see IoC. This is just a naive attempt,
since the way the parameters are passed to the constructor is not very
good (at least in my opinion )
Can someone recommend a better way? A link to an example, or explanation
how it is done, would be best.
Here goes long example :
/// CODE
#include <string>
#include <map>
#include <iostream>
#include <typeinfo>
#include <cassert>
#include <memory>
class I
{
public:
I()
{
}
virtual ~I()
{
}
void foo()
{
doFoo();
}
private:
virtual void doFoo() = 0;
};
class A : public I
{
public:
A( const int v_) : I(),
v( v_ )
{
std::cout<<"A::A() v="<<v<<std::endl;
}
virtual ~A()
{
std::cout<<"A::~A()"<<std::endl;
}
static void setParams( const int nextParam )
{
newCreateParam = nextParam;
}
static I* create()
{
return new A( newCreateParam );
}
private:
virtual void doFoo()
{
std::cout<<"A::doFoo() v="<<v<<std::endl;
}
int v;
static int newCreateParam;
};
int A::newCreateParam=0;
class B : public I
{
public:
B() : I()
{
std::cout<<"B::B()"<<std::endl;
}
virtual ~B()
{
std::cout<<"B::~B()"<<std::endl;
}
static I* create()
{
return new B;
}
private:
virtual void doFoo()
{
std::cout<<"B::doFoo()"<<std::endl;
}
};
std::map< std::string, I* (*)() > GetCreator()
{
std::map< std::string, I* (*)() > m;
m[ typeid(A).name() ] = &A::create;
m[ typeid(B).name() ] = &B::create;
return m;
}
const std::map< std::string, I* (*)() > creator = GetCreator();
I* CreateObj( const std::string whichOne )
{
std::cout<<"Creating new object of type = " << whichOne << std::endl;
for ( std::map< std::string, I* (*)() >::const_iterator it =
creator.begin(); creator.end() != it; ++ it )
{
if ( std::string::npos != it->first.find( whichOne ) )
{
I* (*func)() = it->second;
return func();
}
}
std::cout<<"The creator for the class " << whichOne << " not
found." << std::endl;
return NULL;
}
int main()
{
A::setParams( 55 );
std::auto_ptr< I > newObj1( CreateObj( "B" ) );
std::auto_ptr< I > newObj2( CreateObj( "A" ) );
std::auto_ptr< I > newObj3( CreateObj( "C" ) );
if ( NULL != newObj1.get() )
{
newObj1->foo();
}
if ( NULL != newObj2.get() )
{
newObj2->foo();
}
if ( NULL != newObj3.get() )
{
newObj3->foo();
}
}
/// END OF CODE