簡體   English   中英

從具體類派生抽象模板類

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM