--------
...ist sehr praktisch wenn man ein QObject nicht besitzt oder es sich
-unvermittelt löschen kann. So wie unser Thread.
\ No newline at end of file
+unvermittelt löschen kann. So wie unser Thread.
+
+Wenn ein QObject gelöscht wird werden alle QPointer die darauf zeigen
+auf NULL gesetzt. Man kann das mit isNull() testen.
\ No newline at end of file
#include "thingy.h"
-
+//just default implementations
Thingy::Thingy(){}
Thingy::~Thingy(){}
#include <QString>
+///The Thingy class - it shows how to load library functionality in C++.
+///It is a kind of Plugin.
class Thingy
{
public:
+ ///Create a thingy.
Thingy();
+ ///Delete it.
virtual ~Thingy();
+
+ ///Example for an interface that provides functionality.
+ ///
+ ///Normally these are either pure virtual or have a default implementation
+ ///that makes sense in the context.
+ ///
+ ///Usually a plugin interface has lots and lots of those.
+ ///With or without parameters...
virtual QString getThingy()=0;
};
+///Convenience function pointer type for the factory function.
typedef Thingy* (*ThingyFunc)();
#endif
#include "lib1.h"
-static int mything=1;
-
+///just return something nice for this interface
QString Thingy1::getThingy()
{
return "Thingy1: "+QString::number(mything++);
}
+///the factory function: returns a thingy implementation
+///
+///it creates a derived instance that actually implementats the interface,
+///but it returns a pointer to the abstract interface base class
extern "C" Thingy*getthing(){return new Thingy1;}
\ No newline at end of file
#include "../base/thingy.h"
+///Implementation number 1 of a Thingy.
+///This is one example of a plugin interface implementations.
class Thingy1:public Thingy
{
public:
+ ///implementation of the interface
virtual QString getThingy();
+ private:
+ int mything=1;
};
\ No newline at end of file
#include "lib2.h"
-static int mything=1;
QString Thingy2::getThingy()
{
- return "Completely different Thingy 2: "+QString::number(mything++);
+ return QString("Completely different Thingy 2: %1").arg(mything+=1.1);
}
+///the other factory method, see lib1 for details
extern "C" Thingy*getthing(){return new Thingy2;}
\ No newline at end of file
#include "../base/thingy.h"
+///second implementation of the thingy plugin interface
class Thingy2:public Thingy
{
public:
+ ///return something completely different
virtual QString getThingy();
+ private:
+ ///it is perfectly alright to add data, as long as we have
+ ///a virtual destructor - even if it is implicitly defined
+ double mything=0.;
};
\ No newline at end of file
void MainWin::pokeThread()
{
+ //if we still have that thread: poke it
if(mthread.isNull())
mthingylabel->setText("Sorry, cannot poke a null thread");
else
///call that thingy from one of those libraries
void callThingy();
private:
- //label to show what we are doing
+ ///label to show what we are doing
QLabel*mthingylabel;
- //the library that we loaded
+ ///the library that we loaded
QLibrary*mthinglib;
- //the thingy from that library
+ ///the thingy from that library
Thingy*mthingy;
+ ///smart pointer to the thread example
QPointer<MyThread>mthread;
};
void MyThread::disruptThread()
{
+ //relay this action
emit disruptThreadSignal();
}
void MyTask::disruptThread()
{
+ //go screw with the counter
ctr+=1000;
gotime();
}
///\param slot the slot to call for updates, must be SLOT(foo(QString)) or SLOT(foo())
static MyThread* startMe(QObject*callee,const char*slot);
public slots:
+ ///public interface of the proxy/facade to disrupt the counting of the task
void disruptThread();
signals:
+ ///cascade signal to relay this interface to the task
void disruptThreadSignal();
protected:
///internal: creates the thread and remembers who to call
///runs the thread
void run()override;
private:
- //remember who to call between startMe and run
+ ///remember who to call between startMe and run
QObject*mcallee;
const char*mcallslot;
};