T
Tommi =?UTF-8?B?TcOka2l0YWxv?=
Hi,
I try to implement a factory for classes. There are 2 kinds of them, which
have different constructors. One of them is the base class. The factory
gets all needed parameters in his create-method. I would like to specialize
my factory template depending on the base-class. Here is a (not working)
example:
#include <iostream>
class Base
{
public:
Base()
{ std::cout << "Base::Base()" << std::endl; }
};
class Base2 : public Base
{
int b;
public:
Base2(int b_)
: b(b_)
{ std::cout << "Base2::Base2(" << b_ << ')' << std::endl; }
};
class Derived : public Base
{
public:
Derived()
{ std::cout << "Derived:erived()" << std::endl; }
};
class Derived2 : public Base2
{
public:
Derived2(int d_) : Base2(d_)
{ std::cout << "Derived2:erived2(" << d_ << ')' << std::endl; }
};
template <typename T>
class Factory
{
public:
Base* create(int a)
{ return new T(); }
};
template <>
class Factory<Base2>
{
public:
Base* create(int a)
{ return new Base2(a); }
};
int main()
{
Base* a;
Factory<Base> factoryA;
Factory<Base2> factoryB;
Factory<Derived> factoryC;
Factory<Derived2> factoryD;
a = factoryA.create(1); delete a;
a = factoryB.create(1); delete a;
a = factoryC.create(1); delete a;
a = factoryD.create(1); delete a;
}
As expected Factory<Derived2> does not use the specialization, because
Derived2 is not Base2, but only derived from Base2. Even if the compiler
would use it, it would call "new Base2(int)", but not "new Derived2(int)".
A possible solution is to put a second template-parameter here and pass the
class and its baseclass, but I'm feel, there is a better solution for this.
Tommi
I try to implement a factory for classes. There are 2 kinds of them, which
have different constructors. One of them is the base class. The factory
gets all needed parameters in his create-method. I would like to specialize
my factory template depending on the base-class. Here is a (not working)
example:
#include <iostream>
class Base
{
public:
Base()
{ std::cout << "Base::Base()" << std::endl; }
};
class Base2 : public Base
{
int b;
public:
Base2(int b_)
: b(b_)
{ std::cout << "Base2::Base2(" << b_ << ')' << std::endl; }
};
class Derived : public Base
{
public:
Derived()
{ std::cout << "Derived:erived()" << std::endl; }
};
class Derived2 : public Base2
{
public:
Derived2(int d_) : Base2(d_)
{ std::cout << "Derived2:erived2(" << d_ << ')' << std::endl; }
};
template <typename T>
class Factory
{
public:
Base* create(int a)
{ return new T(); }
};
template <>
class Factory<Base2>
{
public:
Base* create(int a)
{ return new Base2(a); }
};
int main()
{
Base* a;
Factory<Base> factoryA;
Factory<Base2> factoryB;
Factory<Derived> factoryC;
Factory<Derived2> factoryD;
a = factoryA.create(1); delete a;
a = factoryB.create(1); delete a;
a = factoryC.create(1); delete a;
a = factoryD.create(1); delete a;
}
As expected Factory<Derived2> does not use the specialization, because
Derived2 is not Base2, but only derived from Base2. Even if the compiler
would use it, it would call "new Base2(int)", but not "new Derived2(int)".
A possible solution is to put a second template-parameter here and pass the
class and its baseclass, but I'm feel, there is a better solution for this.
Tommi