Nice使用纯虚函数初始化线程

时间:2014-03-22 12:49:56

标签: c++ multithreading virtual

这里我设计了snall Pipe类层次结构,问题是,我想让层次结构最小化到最终用户,所以他唯一要做的就是覆盖虚拟     功能如下:

template <typename T> class Processable{

protected:

public:
    std::thread  processLoop;
    void myWrapper(Processable<T>* pp ){    pp->processLoopFunction();};
    virtual void processLoopFunction() = 0 ;
    Processable(   ):processLoop(&Processable<T>::myWrapper,this,this){ processLoop.detach();};
    ~Processable(  ){};

};


template <typename T>  class Source ;

template <typename T> class Sink : public virtual Processable<T>{


    // virtual void processChunk(void) = 0;
    // virtual void isChunkReady(void) = 0; 
protected:

public:
    Source<T>* mySource;
    Sink():mySource(nullptr){};


};

template <typename T> class Source : public  virtual Processable<T>{

protected:


public:
    lockfreequeue<T>  myOutputDataBuffer;


    void setSink(Sink<T>&);
    virtual void processLoopFunction() = 0 ;
};

template <typename T> class Pipe : public virtual Source<T>, public  virtual Sink<T>{

public:
    virtual void processLoopFunction() = 0 ;

};


template <typename T> Pipe<T>& operator|(Source<T>& lhs, Pipe<T>& rhs  ){ lhs.setSink(rhs) ;return rhs;};

template <typename T> Sink<T>& operator|(Source<T>& lhs, Sink<T>& rhs  ){ lhs.setSink(rhs) ;return rhs;};


template <typename T> class PipeDouble: public Pipe<T>{

public:
    virtual void processLoopFunction()  ;

};    

template <typename T> class OutputSink : public Sink<T>{
public:

    virtual void processLoopFunction() ;

};


template <typename T> void Source<T>::setSink(Sink<T>& pp){        
    pp.mySource = this ;
};      


template <typename T> class FileSource : public Source<T>{
    std::ifstream myInputFile;
public:
    FileSource(string filename):myInputFile(filename){};
    virtual void processLoopFunction()  ;
};

template <typename T> class NumberSource : public  Source<T>{

public:
    NumberSource(){};
    virtual void processLoopFunction() ;           
};        

template <typename T> void OutputSink<T>::processLoopFunction(){   
    T tmp;
    while(true){
    if(this->mySource!=nullptr){
        this->mySource->myOutputDataBuffer.pop(tmp);
        cout << tmp << endl;
    }
    }

}

template <typename T> void FileSource<T>::processLoopFunction(){

    T ll = 0;    

    while(myInputFile >> ll){
    this->myOutputDataBuffer.push(ll);
    }
}

template <typename T> void NumberSource<T>::processLoopFunction(){

    T ll = 0 ; 

    while(true){
    this->myOutputDataBuffer.push(ll);
    ll++;
    ll++;

    }
}    

template <typename T> void PipeDouble<T>::processLoopFunction(){
    T tmp;

    while(true){
        if(this->mySource!=nullptr){
            this->mySource->myOutputDataBuffer.pop(tmp);
            tmp  = tmp + tmp;
            this->myOutputDataBuffer.push(tmp);
        }
    }    
}

当然我最终还是

  

汤姆@奥伯伦:〜/ CPP /管道和GT; ./a.out名为terminate的纯虚方法   在没有活动异常的情况下调用Aborted

但并非总是如此(对于某些派生类,它会抛出该错误,对于其他一些人来说); 除了初始化std :: thread processLoop之外,还有一些很好的方法吗?在每个派生类中分开?

1 个答案:

答案 0 :(得分:0)

不要使用继承。

template<typename T, typename Engine>
struct Processable {
  Engine e;
  std::thread myThread;

  Processable( Processable&& ) = default;
  Processable( Processable & ) = delete;
  Processable( Processable const& ) = delete;
  Processable( Processable const&& ) = delete;
  Processable() = delete;
  Processable& operator=(Processable const&) = delete;
  Processable& operator=(Processable &&) = delete;


  template<typename... Args>
  explicit Processable(Args&& args):
    e( std::forward<Args>(args) ),
    myThread( &Engine::processLoopFunction, &e, &e )
  {
    myThread.detach();
  }
};

现在,客户端使用(非虚拟)processLoopFunction创建引擎类型,然后实例化Procesable<T, Engine>,它会自动为其构建后期工作。它也完美地转发了Engine的构造函数。

但实际上,当你想要的只是一个可调用的对象时,创建一个来做这件事似乎毫无意义。为什么不采用任意类型并在其上调用()而不是命名processLoopFunction方法?

同样地,创建线程对象并将它们分离也不是一个好主意,因为你只是干净关闭基本上是不可能的。

相关问题