Re: templates and Q_OBJECT
Quote:
Originally Posted by TheKedge
I want to pass an instance of any class (provided that the class has a function x()) to the constructor of Logger, so that the Logger can call the func. Is that possible?
Of course it is. That's what interfaces are for.
Code:
class MonitoredObject
{
public:
};
class Fridge : public SomeClass, public MonitoredObject
{
...
QString status
() { if( rand() % 2 ) return "OK";
else return "ON FIRE";
} ...
};
Re: templates and Q_OBJECT
ok, but I'm not sure if that's what I want. I was thinking of something like
Code:
logger::logger (<T*> thingToLog):thing(thingToLog)
{
<T*> thing;
}
logger::doJob()
{
thing->logData();
}
and the object which wants logging to be done makes an instance of a logger thus:
Code:
{
logger = new logger(this);
and provides a func which decides what and how to log things
Code:
logData()
{
logger->log(getOneDatum());
logger->log(getAnotherDatum());
logger->flush();
}
My logger class has a fairly big interface which doesn't really have much to do with the class being logged. I just thought that that might be a good way of doing things since I don't inherit any interface - is it a bad idea? is it a question of having friends or having inheritance? what do you recommend?
thanks for the help
Kev
Re: templates and Q_OBJECT
ahh, one more thing:
when I try:
Code:
class Refrigerator : public BaseDevice, public Logger
thus inheriting the logger
I get a error on trying to connect things:
Code:
connect(view, SIGNAL(elementClicked(int /*index*/, int /*state*/)), fridge, SLOT(setSwitch(int /*index*/, int /*state*/)));
My logger is
and the error is can't uniquely convert from class Refrigerator * to const class QObject *
Will I have to restructure Logger before inheriting it?
K
Re: templates and Q_OBJECT
Quote:
Originally Posted by TheKedge
when I try:
class Refrigerator : public BaseDevice, public Logger
thus inheriting the logger
I get a error on trying to connect things
This is a Qt limitation. The class that inherits QObject must be first:
Code:
class Refrigerator : public Logger, public BaseDevice
Quote:
Originally Posted by TheKedge
connect(view, SIGNAL(elementClicked(int /*index*/, int /*state*/)), fridge, SLOT(setSwitch(int /*index*/, int /*state*/)));
I'm not sure if Qt will like those comments.
Re: templates and Q_OBJECT
ok, but my BaseDevice is also a QObject ..
class BaseDevice : public QThread, public CommPort
where CommPort is not a Qt-based class
(Qt is fine with the comments, they just expand in the macro as comments)
is the template solution (my original scheme) also a limited by Qt?
i.e. Template classes not supported by Q_OBJECT
Code:
#include <QtCore>
template<class T>
class thing
{
Q_OBJECT
public:
thing( T* fridge):m_fridge(fridge) { }
virtual ~thing() { }
private:
T* m_fridge;
};
Re: templates and Q_OBJECT
Quote:
Originally Posted by TheKedge
My logger class has a fairly big interface which doesn't really have much to do with the class being logged. I just thought that that might be a good way of doing things since I don't inherit any interface - is it a bad idea? is it a question of having friends or having inheritance? what do you recommend?
First of all you create a separate thread for each device. If there is a lot of such devices, you will loose a lot of time for context switching. Maybe it will be better if a single logger thread would serve more than one device?
The easiest way is to use an interface, but this requires a small change in all classes that need logging --- you must add another base class. The good news is that you will be able to treat all kinds of devices the same way and for example create a list of pointers that you can traverse and collect data (just be careful when you delete/remove someting).
Another solution is to stick with templates, but the problem is that Qt doesn't handle them. One way is to split the implementation into two classes.
Code:
class BaseLogger
{
public:
virtual void logData() = 0;
};
template< class T >
class Logger : public BaseLogger
{
public:
Logger( T* device );
void logData();
...
};
class LoggerThread
: public QThread{
Q_OBJECT
public:
// user will have to create Logger himself
LoggerThread( BaseLogger * );
// or like this, but I'm not sure if Qt will like it:
template< class T >
static LoggerThread * createLoggerFor( T* device );
void run()
{
if( logger != 0 ) {
logger->logData();
}
}
...
};
After small modifications single logger thread will be able to handle multiple devices, but IMO the interface approach is cleaner.
Re: templates and Q_OBJECT
Quote:
Originally Posted by TheKedge
ok, but my BaseDevice is also a QObject ..
class BaseDevice : public QThread, public CommPort
where CommPort is not a Qt-based class
Qt doesn't use virtual inheritance, so you would end with an object that represents two distinct threads at the same time. Only one of the base classes can be derived from QObject.
Quote:
Originally Posted by TheKedge
Qt is fine with the comments, they just expand in the macro as comments
The question is whether Qt will be able to remove them later when it comes to signature normalization during connection setup.
Quote:
Originally Posted by TheKedge
is the template solution (my original scheme) also a limited by Qt?
i.e. Template classes not supported by Q_OBJECT
Yes, moc can't generate code for template classes, since they require special treatment.
Re: templates and Q_OBJECT
Jacek,
they are great answers!
thanks for the info, especially on Q_OBJECT and threads; I'll put your knowledge to my good use! thanks,
K
Re: templates and Q_OBJECT
@jacek
Code:
template< class T > static LoggerThread * createLoggerFor( T* device );
could u please expain what that fn will do ?
assuming
Code:
template< class T >
class LoggerThread
: public QThread {
Re: templates and Q_OBJECT
Quote:
Originally Posted by sunil.thaha
could u please expain what that fn will do ?
assuming [...]
I don't know what it should do with your assumption, but my idea was not to make LoggerThread a template.
Compare this two:
Code:
LoggerThread *thread = new LoggerThread( new Logger< Fridge >( fridge ) );
LoggerThread *thread = LoggerThread::createLoggerFor< Fridge >( fridge );
In the second example user doesn't have to know anything about the Logger class and yes, your source code is 1 byte shorter ;)
Re: templates and Q_OBJECT
My assumption was wrong.
did not notice the static function :mad: