[英]Deriving an abstract template class from concrete class
假设我有以下课程:
template <typename T>
class CModule{
public:
virtual void process( std::multiamp<int, T>) = 0;
}
和派生类:
template <typename T>
class CModuleDeriv: public CModule<T>{
public:
virtual void process( std::multiamp<int, T>){....};
}
我不想实现此功能的类:
class Client{
std::vector<CModule<T>*> oModuleList_; // <--- this is not possible error
public:
void moduleLoader(){
oModuleList_.resize(1);
if( some_condition ){
oModuleList_[0] = CModuleDeriv<int>();
}else{
oModuleList_[0] = CModuleDeriv<double>();
}
}
}
可能吗? 还有其他解决方案吗? 我不能使用boost:/
首先,将来请发布几乎可以编译的代码(甚至更好的代码!),因为您忽略的那些“小”细节有时会更改代码的语义。 因此,提交几乎可编译的代码几乎具有明确的语义...
这是一些可能会或可能不会解决您问题的代码:
#include<map>
#include<vector>
template <class, class>
class TypedMultimap;
class TypeErasedMultimap {
public:
template <class T1, class T2>
std::multimap<T1,T2> & getMap() {
return static_cast<TypedMultimap<T1,T2> &> (*this); // This is not type safe, it can be made to be, but boost people already did it so I won't bother
}
virtual ~TypeErasedMultimap(){}
};
template <class T1, class T2>
class TypedMultimap: public TypeErasedMultimap, public std::multimap<T1,T2> {};
class CModule{
virtual void process( TypeErasedMultimap &) = 0;
};
template <typename T>
class CModuleDeriv: public CModule{
// At his point, please ask yourself, how will you make sure that the right kind
// of map arrives at this call? I can't answer this, since this is related to
// the semantics...
virtual void process( TypeErasedMultimap & map_){
std::multimap<int,T> &map = map_.getMap<int,T>();
//...
};
};
class Client{
// Why are you using raw pointers?!?
std::vector<CModule*> oModuleList_;
public:
void moduleLoader(){
oModuleList_.resize(1);
if( 1/*some condition*/ ){
oModuleList_[0] = new CModuleDeriv<int>();
}else{
oModuleList_[0] = new CModuleDeriv<double>(); // the types are lost forever...
}
}
// ~Client() you MAY OR MAY NOT!!! need a destructor since your vector is holding pointers: use smart pointers!!!
};
int main() {
}
就其本身而言,这不是解决问题的方法,因为即使未编译的代码段也无法解决任何问题。 您正在将本质上不同类型的事物推到一个通用列表中,并丢失它们的类型,那么您如何知道将来如何使用这些元素? 这是一个语义问题。
我将大胆猜测这可能是您要尝试执行的操作:
#include<boost/variant.hpp>
#include<boost/shared_ptr.hpp>
#include<boost/make_shared.hpp>
#include<map>
#include<vector>
typedef boost::variant<std::multimap<int,int>, std::multimap<int,double> /* possibly some others */ > VariantMap;
class CModule{
public:
virtual void process( VariantMap &) = 0;
};
class CModuleDeriv1: public CModule, public boost::static_visitor<> {
public:
virtual void process( VariantMap & in){
boost::apply_visitor(*this, in);
};
template < class T>
void operator()(std::multimap<int,T> & in) {
// do your type safe processing here
}
};
class CModuleDeriv2: public CModule, public boost::static_visitor<>{
public:
virtual void process( VariantMap & in){
boost::apply_visitor(*this, in);
};
template < class T>
void operator()(std::multimap<int,T> & in) {
// do other kind of processing here
}
};
class Client{
// Why are you using raw pointers?!?
std::vector<boost::shared_ptr<CModule> > oModuleList_;
public:
void moduleLoader(){
oModuleList_.resize(1);
if( 1/*some condition*/ ){
oModuleList_[0] = boost::make_shared<CModuleDeriv1>();
}else{
oModuleList_[0] = boost::make_shared<CModuleDeriv1>(); // the types are safe now, even though not known
}
}
// ~Client() you MAY OR MAY NOT!!! need a destructor since your vector is holding pointers: use smart pointers!!!
};
int main() {
}
看到,没有更多评论na :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.