You are not logged in.

Dear visitor, welcome to QtForum.org. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

FatScouser

Beginner

  • "FatScouser" is male
  • "FatScouser" started this thread

Posts: 11

Location: Brackley

Occupation: Developer

  • Send private message

1

Tuesday, January 4th 2005, 3:48pm

Inheriting slots : pros and cons

Yo all -

Does anyone have good reasons for or against inheriting slot fns, rather than getting Qt to call derived them directly? E.g. which is better below, scenario A or scenario B?:


Scenario A: using C++ inheritance on a slot
==================================

class MyBaseA : public QObject
{
Q_OBJECT
. . .
public slots:
virtual void mySlot(); // overridable slot
};

class MyDerivedA : public MyBaseA
{
public:
void mySlot(); // this is NOT a slot, just an override of MyBaseA::mySlot()
};

MyBaseA::makeConnections()
{
// Connects to slot MyBaseA::mySlot(). However, MyDerivedA::mySlot()
// always gets called thanks to C++ inheritance.
connect( obj, SIGNAL(mySignal()), this, SLOT(mySlot()));
}


Scenario B: Qt calls the a slot directly
=============================

class MyBaseB : public QObject
{
Q_OBJECT
. . .
public slots:
void mySlot(); // ordinary slot
};

class MyDerivedB : public MyBaseB
{
Q_OBJECT // (incidentally, is this required ???!)

public slots:
void mySlot(); // ordinary slot
};

MyBaseB::makeConnections()
{
// Connects to either MyBaseB::mySlot() or MyDerivedB::mySlot(),
// depending on whether *this is MyBaseB or MyDerivedB.
connect( obj, SIGNAL(mySignal()), this, SLOT(mySlot()));
}


It seems to me that scenario A is superior: we only require a single slot in the base class - and so only a single Q_OBJECT framework (i.e. MOC file).

In scenario B, we have two independent moc frameworks (i.e. moc files), and it may not be obvious which of the two mySlot() fns is called by MyBaseB::makeConnections(): it all depends on whether *this is a pointer to a MyBaseB or to a MyDerivedB.

If anyone has anything to add, or can see something wrong in my argument, please reply! Cheers!

  • "wysota" is male

Posts: 4,276

Location: Warsaw, POLAND

  • Send private message

2

Tuesday, January 4th 2005, 4:07pm

What is the mySlot(); function in MyDerivedA for? It is not a slot anymore so overriding it may only cause problems. I don't know if QObject will let you connect anything to mySlot() at all as I don't think it will check the base class while connecting and in MyDerivedA there is no slot mySlot(), so redefining mySlot as a non-slot function makes no sense to me.

FatScouser

Beginner

  • "FatScouser" is male
  • "FatScouser" started this thread

Posts: 11

Location: Brackley

Occupation: Developer

  • Send private message

3

Tuesday, January 4th 2005, 4:25pm

MyDerivedA::mySlot() was made an ordinary non-slot fn precisely to remove the Qt framework from class MyDerivedA. I have other classes similarly derived off MyBaseA, and it seemed that rather than adding Q_OBJECT to each of them I only need a single slot in the base class. Qt only connects to this base class (MyBaseA), sure, but thanks to the slot being virtual, the vtable will call MyDerivedA::mySlot() (or whichever derived class is involved).

In scenario B - again please consider not just MyDerivedB, but multiple subclasses - Q_OBJECT must be added to every derived class, which seems wasteful.

So rather than applying the Qt framework to every derived class (Screnario B), inheriting a slot fn means I only need apply it to the base class and C++ the vtable does the rest. Do you think this sounds reasonable? To quote from Qt Assistant (page 'Signals and Slots'):

"You can also define slots to be virtual, which we have found quite useful in practice."

Is this one such reason for using virtual slots?

  • "wysota" is male

Posts: 4,276

Location: Warsaw, POLAND

  • Send private message

4

Tuesday, January 4th 2005, 5:19pm

The primary advantage of using virtual slots is that you can reimplement the behaviour of the slot in a subclass. In your case I think the slot doesn't need to be virtual, because the derived class will probably be used in its base class context ( MyBaseA *a = new MyDerivedA(); ). In such case non-virtual slot is sufficient, because you don't change the slots behaviour.

Personaly I don't think adding Q_OBJECT is a big waste as we tend to waste more resources in other situations, so I think we can spare additional tens of bytes in this context :)

  • "Petr Svetr Killometr" is male

Posts: 55

Location: Czech Republic

  • Send private message

5

Wednesday, January 5th 2005, 7:09am

RE: Inheriting slots : pros and cons

I think scenario B is more readable and scenario A is blind. Imagine that MyBaseA and MyDerivedA are in different headers and somebody looking to header with MyDerivedA. How can he uncover that he can use MyDerivedA::mySlot as a slot?

6

Wednesday, January 5th 2005, 8:40am

scenario B is more easier to use comparing to the scenario A. Maybe FatScouser will more prefer to the scenario A, but as i was learning for the past 1 month, i found that signal and slots by QT are the most easiest way to connect.
I know i'm not as good as you, but I've try too. :(
Gimme more time and I'll be as good as you. ;)

  • "wysota" is male

Posts: 4,276

Location: Warsaw, POLAND

  • Send private message

7

Wednesday, January 5th 2005, 8:59am

BTW. I think Q_OBJECT macro isn't required in B, because you don't add any new slots.

FatScouser

Beginner

  • "FatScouser" is male
  • "FatScouser" started this thread

Posts: 11

Location: Brackley

Occupation: Developer

  • Send private message

8

Wednesday, January 5th 2005, 9:47am

?

Wysota, I don't understand: MyDerivedB::mySlot() has been added as new slot, so surely you do need Q_OBJECT? Without Q_OBJECT in MyDerivedB, qt_invoke() won't be expanded out so how wil MyDerivedB::mySLot() ever be called?

Am I missing something?

FatScouser

Beginner

  • "FatScouser" is male
  • "FatScouser" started this thread

Posts: 11

Location: Brackley

Occupation: Developer

  • Send private message

9

Wednesday, January 5th 2005, 10:00am

RE: Inheriting slots : pros and cons

Petr,

Maybe the name mySlot() helps somewhat! (no offence!)
Sure, I agree things are not crystal clear with ScenarioA, but one could make it clearer with the following:

class MyDerivedA :public MyBaseA
{
...
public:
virtual mySlot(); // override of slot in MyBasA
};

Since slots are just normal C++ fns, I thought it better to use native C++ inheritance and get MyDerivedA::mySlot() called this way rather than adding a fresh Qt framework into the derived class.

Thanks to everyone's input: I'm still unconvinced which scenario is best, however. Humph ...

  • "wysota" is male

Posts: 4,276

Location: Warsaw, POLAND

  • Send private message

10

Wednesday, January 5th 2005, 11:14am

Re: ?

Quoted

Originally posted by FatScouser
Wysota, I don't understand: MyDerivedB::mySlot() has been added as new slot, so surely you do need Q_OBJECT? Without Q_OBJECT in MyDerivedB, qt_invoke() won't be expanded out so how wil MyDerivedB::mySLot() ever be called?

Am I missing something?


A slot with that name (and signature) is present in MyBaseB and Q_OBJECT macro is there so the whole signal/slot architecture is present, so adding Q_OBJECT to MyDerivedB will not do anything unless new slots appear. Please remember that Qt's signal/slot signatures are text-based.

  • "wysota" is male

Posts: 4,276

Location: Warsaw, POLAND

  • Send private message

11

Wednesday, January 5th 2005, 11:16am

RE: Inheriting slots : pros and cons

Quoted

Originally posted by FatScouser
Thanks to everyone's input: I'm still unconvinced which scenario is best, however. Humph ...


IMO B is better, because it's clear and you don't gain anything with A. Just get rid of the Q_OBJECT macro from MyDerivedB :)