2012-10-04 82 views
0

比方说,我有以下类:派生一个抽象模板类从具体类

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>){....}; 

} 

和类在那里我wan'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:/

+0

请编辑给我的答案 – enobayram

回答

0

首先,将来请发布几乎可以编译的代码(或者编译更好的代码!),因为您省略的那些“小”细节有时会改变您的语义码。因此,提交几乎编译代码几乎已经明确的语义...

下面是一些代码,可能会或可能不会解决你的问题:

#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() { 
} 

这本身是不是你的问题的解决方案,因为你的不编译代码snipplet即使编译也不会解决任何问题。你将具有固有不同类型的东西推到一个共同的列表中并丢失它们的类型,那么你将如何知道如何使用这些元素呢?这是一个语义问题。

我会胡乱猜测,这是你想要做的可能就是:

#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() { 
} 

见,没有更多的评论耿耿于怀:)