get subclass type through the base class pointer
Given the class layout (Base->Derived; Base->Derived2), and the fact that I hold the instance to the derived classes as base class pointer (Base* baseder2 = new Derived2
), I'd like to be able to instantiate the TemplClass instance with the derived type (something like sh = new TemplClass<Derived2>(baseder2)
). The code below instant开发者_运维问答iates
sh = new TemplClass<Base>(baseder2)
, which leads to compile error due to the fact that the fn function
is not declared in class Base
. How can I find out the derived type of baseder2
pointer, preferably without dynamic_cast? Real life code has lots of Base descendants, so I'd like to avoid if statements with dynamic_cast. I was looking into boost::type_traits, but don't what to do with that, to be honest.
Template function template <typename T> BaseTemplClass* foo(T* t)
is just lame excuse for factory obj.
best regards, dodol
class Base
{
public:
virtual ~Base(){}
};
class Derived : public Base
{
public:
virtual ~Derived(){}
void function()
{
std::cout<<"This is Derived"<<std::endl;
}
};
class Derived2 : public Base
{
public:
virtual ~Derived2(){}
void function()
{
std::cout<<"This is Derived2"<<std::endl;
}
};
class BaseTemplClass
{
public:
virtual void Print() =0;
};
template <class Tmodel>
class TemplClass : public BaseTemplClass
{
public:
TemplClass(Tmodel* m)
{
model = m;
}
void Print()
{
model->function();
std::cout << " TemplClass"<<typeid(model).name() << std::endl;
}
Tmodel *model;
};
template <typename T> BaseTemplClass* foo(T* t)
{
BaseTemplClass* sh;
std::cout << "FOO: "<<typeid(t).name() << std::endl;
sh = new TemplClass<T>(t);
return sh;
}
int main(int argc, char **argv)
{
Derived* der = new Derived;
Derived2* der2 = new Derived2;
Base* baseder2 = new Derived2;
BaseTemplClass* sh = foo(der);
sh->Print();
delete sh;
sh = foo(der2);
sh->Print();
delete sh;
sh = foo(baseder2);
sh->Print();
delete sh;
delete der;
delete der2;
delete baseder2;
return 0;
}
Would it make more sense to make function
abstract in Base
so that you don't need to know which derived class it is?
This is not possible. Template parameter types have to be determined at compile time, but the actual type of a pointer can only be determined at run time.
Is template class really needed in your situation? In the given example you may add method "function" to the base class, and make it virtual.
But if you still need template classes, following is possible:
class Base
{
public:
virtual ~Base(){}
virtual BaseTemplClass* createTemplClass() = 0;
};
class Derived : public Base
{
public:
virtual ~Derived(){}
void function()
{
std::cout<<"This is Derived"<<std::endl;
}
virtual BaseTemplClass* createTemplClass()
{
return new TemplClass<Derived>( this );
}
};
class Derived2 : public Base
{
public:
virtual ~Derived2(){}
void function()
{
std::cout<<"This is Derived2"<<std::endl;
}
virtual BaseTemplClass* createTemplClass()
{
return new TemplClass<Derived2>( this );
}
};
template <typename T> BaseTemplClass* foo(Base* t)
{
BaseTemplClass* sh;
std::cout << "FOO: "<<typeid(t).name() << std::endl;
sh = t->createTemplClass();
return sh;
}
精彩评论