Re: MOC and macro expanding
I don't know about macros, but you can use a simple base class to do that:
Code:
Q_OBJECT
signals:
void error(Errors::ErrorCodes errorCode);
void warning(Warnings::WarningCodes warningCode);
};
class Compressor : public Notifier
{
Q_OBJECT
}
It is much cleaner and now it is easier to add new functionality to all the signal-sending objects in the hierarchy. It will work in both Qt4 and Qt5 too.
If you have a lot of common code, macros will get messy very quickly.
Another thing, does it really make sense for an object to be an "error sender" without being a "warning sender" ? If something can report an error, surely it should be able to report a warning.
Anyway, I'd go for common functionality via base class instead of macros.
Re: MOC and macro expanding
Quote:
but you can use a simple base class to do that
That was my first idea before creating any macros. The problem is that Qt classes don't support multiple inheritance from QObject-based classes. More correctly, there can be only one QObject-based parent and it should be first one in inheritance ierarchy. Lets say I use that Notifier class you suggested, and I have two other classes:
class A : public QMainWindow
and
class B : public QDialog
I want them both use my error() and warning() signals, connected to single object who shows user all errors and warnings from the whole program. However, I can't inherit from Notifier and QMainWindow or Notifier and QDialog - they are both based on QObject already.
Quote:
Another thing, does it really make sense for an object to be an "error sender" without being a "warning sender" ? If something can report an error, surely it should be able to report a warning.
Its for possible future program expanding. However, it will not work with a single macro anyway.
Re: MOC and macro expanding
You can use composition instead of inheritance (so the mainWindow or dialog instance "contains" a notifier object).
If you want to stick to inheritance, then the "Notifier" class does not have to be QObject-based:
Code:
// helper class used to maintain the connections
class NotifierHelper
: public QObject{ Q_OBJECT
signals:
void error(Errors::ErrorCodes errorCode);
void warning(Warnings::WarningCodes warningCode);
};
// "error reporting" base class, not based on QObject
class Notifier
public:
void error(Errors::ErrorCodes errorCode){
this->_sender.error(errorCode); // you can invoke signals directly, like method calls (in fact they are methods)
}
void addErrorReceiver
(QObject * receiver,
const char * signal_or_slot
){ QObject::connect(&_sender,
SIGNAL(error
(Errors
::ErrorCodes)), receiver, signal_or_slot
);
}
private:
NotifierHelper _sender;
};
class Compressor : public Notifier
{
Q_OBJECT
public:
void functionWithError(){
SomeReceiver receiver;
this->addErrorReceiver(&receiver, SLOT(receiveError(ErrorCodes)));
// now the 'receiver' object will get the error signal
this->error(Errors::SomeErrorCode);
}
}
There exists quite a lot of object-oriented programming languages without the macro expansion feature. Just imagine how would you solve this problem in one of these languages.
Re: MOC and macro expanding
Quote:
You can use composition instead of inheritance (so the mainWindow or dialog instance "contains" a notifier object).
Yes, but I don't like it. It's kind of "OOP-hack" for me, because architecturally it is inventing another class and making another object when you just want to make base class realise an interface.
Quote:
If you want to stick to inheritance, then the "Notifier" class does not have to be QObject-based
It is an encapsulation of composition. Looks like I will use this, though it's not OOP-pure. Yes, macros are not pure too :D
Quote:
There exists quite a lot of object-oriented programming languages without the macro expansion feature. Just imagine how would you solve this problem in one of these languages.
Using interfaces?
Going to composition-inheritance combination, thank you.