Results 1 to 13 of 13

Thread: External Acces to Private Slot

  1. #1
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default External Acces to Private Slot

    Should class A really be able to connect to a private slot in class B?

    Here's some pseudo code to illustrate what I mean:
    Qt Code:
    1. class A : public QObject
    2. {
    3. A() {
    4. instanceOfB = new B();
    5. connect(this, SIGNAL(mySignal()), instanceOfB, SLOT(MySlot()));
    6. }
    7.  
    8. signals:
    9. void mySignal();
    10.  
    11. private:
    12. B* instanceOfB;
    13. }
    14.  
    15. class B : public QObject
    16. {
    17. private slots:
    18. void MySlot();
    19. }
    To copy to clipboard, switch view to plain text mode 

    This effectively means that a class B private function can be accessed by class A, which is not really in the spirit of private function access specifier.

  2. #2
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: External Acces to Private Slot

    You can't call the slot directly, but you can call it via the slot mechanism as those are resolved during run time.

  3. #3
    Join Date
    Apr 2010
    Location
    Rostov-na-Donu, Russia
    Posts
    153
    Thanks
    2
    Thanked 26 Times in 23 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: External Acces to Private Slot

    slots are not a usual functions. they are a part of metaObject. when you emitting signal slot is not called directly like this
    Qt Code:
    1. obj->slotName( params );
    To copy to clipboard, switch view to plain text mode 
    emitting signal say to object to call it's function like this:
    Qt Code:
    1. obj->invokeMethod( "slotName" // you see - in quotes
    2. , params );
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jul 2009
    Location
    Enschede, Netherlands
    Posts
    462
    Thanked 69 Times in 67 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: External Acces to Private Slot

    Maybe as an extra idea:

    Qt Code:
    1. connect(A, SIGNAL(foo()), B, SLOT(bar()));
    To copy to clipboard, switch view to plain text mode 
    If object A emits signal foo(), then object B should execute function bar().

    This system is an implementation of a language level observer pattern, in which object B reacts to something that object A does, rather than object A triggering something in object B.
    Last edited by franz; 17th July 2010 at 13:03. Reason: spelling corrections
    Horse sense is the thing that keeps horses from betting on people. --W.C. Fields

    Ask Smart Questions

  5. #5
    Join Date
    Jun 2010
    Posts
    86
    Thanks
    10
    Thanked 6 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: External Acces to Private Slot

    Signal-Slot pattern aim is that the sender DOESN'T KNOW which slots will be called via its signal.
    so actually the sender doesn't call the slot, he just emits the signal and the environment deals with it.

  6. #6
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default

    You all make valid points. I'm definitely not criticizing Qt's SIGNAL / SLOT mechanism.

    My observation is merely that class A would be able to execute a private slot on class B. There is no way that class B can prevent its private slot (which is actually just a private function that is registered as part of the associated metaObject) from being run by any other SIGNAL / SLOT aware class.

    Say for instance that I want to create a private slot on class B that should only be run by class B:

    Qt Code:
    1. class B : public QObject
    2. {
    3. private slots:
    4. void MyVeryPrivatePersonalSlot(); // I, class B, should be the only class able to run the code in this function
    5. }
    To copy to clipboard, switch view to plain text mode 

    But the private slot can be "called" (or triggered) by any class that can emit signals. So really the slot is not private at all.

    Qt Code:
    1. class A : public QObject
    2. {
    3. A() {
    4. instanceOfB = new B();
    5. connect(this, SIGNAL(mySignal()), instanceOfB, SLOT(MyVeryPrivatePersonalSlot()));
    6. }
    7.  
    8. signals:
    9. void mySignal();
    10.  
    11. private:
    12. B* instanceOfB;
    13. }
    To copy to clipboard, switch view to plain text mode 

    Is there any way to prevent this behaviour, i.e. keep private slots truly private?

    Signal-Slot pattern aim is that the sender DOESN'T KNOW which slots will be called via its signal.
    so actually the sender doesn't call the slot, he just emits the signal and the environment deals with it.
    I agree with you and this is all well and good when slot bar() is public. But when slot bar() is private, class B has no control over who can trigger the execution of the private slot's code.

    Quote Originally Posted by ahmdsd_ostora View Post
    Signal-Slot pattern aim is that the sender DOESN'T KNOW which slots will be called via its signal.
    so actually the sender doesn't call the slot, he just emits the signal and the environment deals with it.
    But in the case when class A, the sender (signaller), connect's its signal to class B's private slot (as in my example), then it does know exactly which function should be executed and it can choose to have code in private functions executed. In C++ this can be achieved using friends, but still class B would decide who its friends are so it still have the control.

    I understand that the code isn't being called directly - it's being done through the metaObject framework, but the end effect is that a private function is exposed.

    Quote Originally Posted by borisbn View Post
    slots are not a usual functions. they are a part of metaObject. when you emitting signal slot is not called directly like this
    Qt Code:
    1. obj->slotName( params );
    To copy to clipboard, switch view to plain text mode 
    emitting signal say to object to call it's function like this:
    Qt Code:
    1. obj->invokeMethod( "slotName" // you see - in quotes
    2. , params );
    To copy to clipboard, switch view to plain text mode 
    I agree and it's useful framework and I do understand (more or less) how the framework actually works. My concern is that private slots are available to anyone and everyone, and this breaks part of the C++ class member access pattern.

    Quote Originally Posted by fatjuicymole View Post
    You can't call the slot directly, but you can call it via the slot mechanism as those are resolved during run time.
    I disagree, but I'm very happy to be proved wrong.

    A slot is nothing other than a function on a class and can be called the same way that any other function on a class would be called. But it is also considered when building the metaObject and is made available through the signal / slot mechanism. When the slot is called as a normal function the access specifier (public, protected, private) is respected. When the slot is triggered by a signal (whether the class' own signal or a signal from another class), the access specifier is not respected, resulting in private functions (slots) being runnable (triggerable) from outside the class.

    The net effect is that private slots can be run by anyone.
    Last edited by wysota; 20th July 2010 at 00:03.

  7. #7
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: External Acces to Private Slot

    Maybe you were confused by my response, as it basically states exactly the same as what you just replied with. Eg. that obj->func() will not work from outside the class but obj->InvokeMethod will.

    To have your slots truly private, create them in another private class, and contain a pointer to this class in the private part of your public class. So if you need to access your private slots you can do d->slot() whilst people outside your class can not, as 'd' would be private.

    This also means your class is more flexible - you can either have data for each instance of your class, or you can share data between instances of your class (like the Qt object classes).

  8. The following 3 users say thank you to squidge for this useful post:

    borisbn (20th July 2010), stefanadelbert (19th July 2010), Zlatomir (19th July 2010)

  9. #8
    Join Date
    Jun 2010
    Posts
    86
    Thanks
    10
    Thanked 6 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: External Acces to Private Slot

    I think that Qt should prevent connecting to private slots outside their classes.

  10. #9
    Join Date
    Apr 2010
    Posts
    769
    Thanks
    1
    Thanked 94 Times in 86 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: External Acces to Private Slot

    Slots, by their nature, are public, period. Private slots make no sense; private members are not accessible outside the class they belong to, so signals and slots make no sense, since a direct function call will do just as well in such instances. Slots are inherently public; they are meant explicitly for inter-class communication.

    The whole pedantic discussion above would make more sense if protected slots were the topic. For private slots, it's just silly. And the protected case is actually more interesting; here, in order to preserve the traditional C++ meaning of "protected", the metadata system would have to keep track of object inheritance to ensure that only related classes could signal one another - which, again, is somewhat silly since the whole point is inter-object communication, but here it's somewhat less silly than it is when the topic is private slots. In the end, however, one would have to reproduce a signficant chunk of the C++ compiler in order to pull this sort of thing off.

    And for what purpose? The goto statement is also considered "bad", but lots of people still use it, and even modern languages like Java support it despite being able to do perfectly well without it through the use of other, "better" constructs. Varying degrees of access protection are useful, but insisting on strict adherence to this paradigm in a signalling system is pointless. Anyone concerned about this is, presumably, a programmer. By implication, that means you should be aware of the potential pitfalls, and should simply avoid them.

  11. The following 2 users say thank you to SixDegrees for this useful post:

    stefanadelbert (19th July 2010), Zlatomir (19th July 2010)

  12. #10
    Join Date
    Apr 2010
    Posts
    769
    Thanks
    1
    Thanked 94 Times in 86 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: External Acces to Private Slot

    Why? What practical problem are you trying to solve through such a constraint? And why are you using slots within a class to begin with? There's no point in using a signalling mechanism inside a single class; you've already got access to plain, old-fashioned function calls.

    Slots are inherently public, by their very nature; see above.

  13. #11
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: External Acces to Private Slot

    Quote Originally Posted by ahmdsd_ostora View Post
    I think that Qt should prevent connecting to private slots outside their classes.
    Considering how the connect() statement works, this would be impossible to do at compile time, and we know that a LOT of people simply ignore the standard output, so wouldn't see the error message about connecting to a private slot at runtime. The end result would just be confusion: "Why isn't my slot being called?". We have enough of this questions on this board already, we don't need more by making the system even more restrictive. If you really want private slots there is a way of doing it by using a private class (see above), else the documentation for your class structure would clearly indicate that the slot you are trying to use is private, and surely you don't blindly bind signals to slot without checking the docs first?

  14. #12
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default

    Quote Originally Posted by fatjuicymole View Post
    Maybe you were confused by my response, as it basically states exactly the same as what you just replied with. Eg. that obj->func() will not work from outside the class but obj->InvokeMethod will.

    To have your slots truly private, create them in another private class, and contain a pointer to this class in the private part of your public class. So if you need to access your private slots you can do d->slot() whilst people outside your class can not, as 'd' would be private.

    This also means your class is more flexible - you can either have data for each instance of your class, or you can share data between instances of your class (like the Qt object classes).
    Nice suggestion. Thanks.

    Quote Originally Posted by ahmdsd_ostora View Post
    I think that Qt should prevent connecting to private slots outside their classes.
    This is basically what I'm saying. I don't believe that it should be possible for a private slot to be accessible outside that defining class.

    Quote Originally Posted by SixDegrees View Post
    Slots, by their nature, are public, period. Private slots make no sense; private members are not accessible outside the class they belong to, so signals and slots make no sense, since a direct function call will do just as well in such instances. Slots are inherently public; they are meant explicitly for inter-class communication.

    The whole pedantic discussion above would make more sense if protected slots were the topic. For private slots, it's just silly. And the protected case is actually more interesting; here, in order to preserve the traditional C++ meaning of "protected", the metadata system would have to keep track of object inheritance to ensure that only related classes could signal one another - which, again, is somewhat silly since the whole point is inter-object communication, but here it's somewhat less silly than it is when the topic is private slots. In the end, however, one would have to reproduce a signficant chunk of the C++ compiler in order to pull this sort of thing off.

    And for what purpose? The goto statement is also considered "bad", but lots of people still use it, and even modern languages like Java support it despite being able to do perfectly well without it through the use of other, "better" constructs. Varying degrees of access protection are useful, but insisting on strict adherence to this paradigm in a signalling system is pointless. Anyone concerned about this is, presumably, a programmer. By implication, that means you should be aware of the potential pitfalls, and should simply avoid them.
    Thanks for your (fueled) response and your good points. Let's not get started on the inheritance of signals and slots though. It's clearly something that the Qt Keepers are aware of and it might be fixed up down the line.

    I take your point about Qt signals and slots being an inter-class communication mechanism, but it is also very useful in other situations. For example,

    Class A has a QTimer. It wants to do something private (modify some or other private member) when the timer times out. It connects signal QTimer::timeout() to its (private) slot MyVeryPrivateSlot(). But now that private slot can be connected to and triggered by anyone outside the class. Sure class A could call private function MyVeryPrivateFunction(), but how else could class A respond to QTimer::timeout() other than with a slot?

    It was not my intention to enter into a ridiculously pedantic debate on the intricacies of Qt's signalling framework. I'm a fan, else I wouldn't be here. Just wanted to get some opinions on the topic and find out if there were any creative solutions.
    Last edited by stefanadelbert; 20th July 2010 at 00:27.

  15. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: External Acces to Private Slot

    There is a nice button on this forum under every post called "Multi-Quote This Message". Please use it next time instead of posting multiple posts.

    As for the discussion: remember that access protection is done purely during compilation based on a very simple rule, there is no actual check made (run-time) whether one can call a particular method or not hence enforcing such check during run-time for Qt slots would only create overhead without any practical benefits. Many languages (like Python) have simply ignored access protection and treat all methods and fields as public. Working around protection in C++ requires 4-5 lines of code so if someone wants to have access to a private or protected member of some class, there is practically no way of stopping him. On pure academic level I can understand that Qt should support access protection to its signals and slots but as an engineer I say there is no practical argument to support this claim.

    but how else could class A respond to QTimer::timeout() other than with a slot?
    Through events.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  16. The following user says thank you to wysota for this useful post:

    stefanadelbert (20th July 2010)

Similar Threads

  1. Timer not connecting to private SLOT
    By been_1990 in forum Qt Programming
    Replies: 4
    Last Post: 16th December 2009, 00:07
  2. Acces parent object
    By Nightfox in forum Qt Programming
    Replies: 8
    Last Post: 19th August 2009, 08:56
  3. Acces a stacked widget...?
    By ucomesdag in forum Qt Programming
    Replies: 5
    Last Post: 25th November 2006, 14:05
  4. Acces to a remote mysql server
    By Alienxs in forum Qt Programming
    Replies: 2
    Last Post: 19th August 2006, 03:10
  5. Replies: 2
    Last Post: 4th May 2006, 19:17

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.