PDA

View Full Version : Threading an instance of a class which has no dependency upon Qt



menasce
17th December 2010, 16:30
I need to be able to launch a sub-classed QThread in such a way that the run() protected method of QThread calls different objects depending upon a class-member variable. Let's see an example.

This is the header of my sub-classed QThread:


#ifndef THREADLAUNCHER_H
#define THREADLAUNCHER_H

#include <QThread>
#include "someProcess.h"

class threadLauncher : public QThread
{
Q_OBJECT
public:
void run() ;
void setClass(someProcess * aProcess) ;
private:
someProcess * theProccess_ ;
};

#endif

Now the source-code of the implementation:


#include "someProcess.h"
#include "threadLauncher.h"

void threadLauncher::run()
{
theProccess_->compute() ;
}

void threadLauncher::setClass(someProcess * aProcess)
{
theProccess_ = aProcess ;
}

In the main program this is the way I launch the thread:


int main()
{
QApllication app() ;

someProcess * theProcessA_ = new someProcess() ;

threadLauncher * theThreadLauncher_ = new threadLauncher() ;
theThreadLauncher_->setClass(theProcessA_) ;
theThreadLauncher_->start() ;

app.exec() ;
}

This is working fine: now comes the tricky part (and my question).
I would like to execute different things in the re-implemented 'run' method. One (trivial) possibility could be:


int main()
{
QApllication app() ;

someProcess * theProcessA_ = new someProcess() ;
classBDefinition * theProcessB_ = new classBDefinition() ;

threadLauncher * theThreadLauncher_ = new threadLauncher() ;
theThreadLauncher_->setClass(theProcessA_) ;
theThreadLauncher_->start() ;

theThreadLauncher_->setClass(theProcessB_) ;
theThreadLauncher_->start() ;

app.exec() ;
}

This would allow me to launch two completely different computations (implemented in different classes) using a single instance of a threadLauncher. My problem at this point is how to make the mechanism general (template?). Infact, to be able to run the latter example I should modify the threadLauncher to become the following:


#ifndef THREADLAUNCHER_H
#define THREADLAUNCHER_H

#include <QThread>
#include "someProcess.h"
#include "classBDefinition.h"

class threadLauncher : public QThread
{
Q_OBJECT
public:
void run() ;
void setClass(someProcess * aProcess) ;
void setClass(classBDefinition * aProcessB) ;
private:
someProcess * theProccessA_ ;
classBDefinition * theProccessB_ ;
};

#endif

and the source, accordingly:


#include "someProcess.h"
#include "threadLauncher.h"

void threadLauncher::run()
{
if( theProccessA_ ) theProccessA_->compute() ;
if( theProccessB_ ) theProccessB_->compute() ;
}

void threadLauncher::setClass(someProcess * aProcess)
{
theProccessA_ = aProcess ;
}

void threadLauncher::setClass(classBDefinition * aProcess)
{
theProccessB_ = aProcess ;
}

This is obviously not manageable should the possibilities increase. My first though was to make the threadLauncher a template class, but since it inherits from a QThread I cannot (I was thinking something like this would do:


#ifndef THREADLAUNCHER_H
#define THREADLAUNCHER_H

#include <QThread>

template <class T> threadLauncher : public QThread
{
Q_OBJECT
public:
void run() ;
void setClass(T * aProcess) ;
private:
T * theProccessA_ ;
};

#endif

I know this is absolutely incorrect C++, I meant it just to convey the basic idea.

Is there some useful suggestion I could receive?

Thanks

high_flyer
17th December 2010, 16:43
Before getting in to details - have you checked QtConcurrent (http://doc.trolltech.com/latest/threads-qtconcurrent.html)?
It looks to me, your case exactly meant for that.
It will save you the whole sub classing issue.