Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. qobject_cast and dynamic cast fail, while static_cast seems to work
Forum Update on Monday, May 27th 2025

qobject_cast and dynamic cast fail, while static_cast seems to work

Scheduled Pinned Locked Moved General and Desktop
qobjectcastdynamiccaststaticcastqsslsocketdisconnected
8 Posts 3 Posters 6.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bart_Vandewoestyne
    wrote on last edited by Bart_Vandewoestyne
    #1

    I have a class ClientSslSocket that is derived from QSslSocket and has the Q_OBJECT macro:

    class ClientSslSocket : public QSslSocket
    {
        Q_OBJECT
        ...
    };
    

    Somewhere in a method of another class FooBar, the disconnected() signal of this class is connected to the disconnectedCallback() slot in FooBar:

    bool FooBar::initializeSocket(ClientSslSocket* socket)
    {
        ...
        connect(socket, SIGNAL(disconnected()), this, SLOT(disconnectedCallback()));
        ....
    }
    

    In the disconnectedCallback() slot, I noticed that dynamic_cast and qobject_cast did not work, but static_cast does seem to work as expected:

    ClientSslSocket* sender1 = dynamic_cast<ClientSslSocket*>(sender());  // returns 0
    ClientSslSocket* sender2 = qobject_cast<ClientSslSocket*>(sender());  // returns 0
    ClientSslSocket* sender3 = static_cast<ClientSslSocket*>(sender());  // seems to work...
    

    I don't understand or see why qobject_cast and dynamic_cast return 0 here, indicating that the qobject/dynamic cast didn't succeed... although this looks like a simple signal-slot connection. What am I overlooking here, or what should I look for to diagnose this any further?

    Kind regards,
    Bart

    1 Reply Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      Add qDebug() << sender(). What do you see?

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      B 1 Reply Last reply
      0
      • yeckelY Offline
        yeckelY Offline
        yeckel
        wrote on last edited by
        #3

        Hi Bart,

        qobject_cast should work as long as everything is QObject inherited. I've tested your code and
        SlientSslSocket* sender2 = qobject_cast<SlientSslSocket*>(sender());
        and it's working (qt 5.5, gcc 4.8.4). I thing there might be problem how is your socket for the method initializeSocket(ClientSslSocket* socket) created. Could you paste longer example?

        B 1 Reply Last reply
        0
        • JKSHJ JKSH

          Add qDebug() << sender(). What do you see?

          B Offline
          B Offline
          Bart_Vandewoestyne
          wrote on last edited by
          #4

          @JKSH said:

          Add qDebug() << sender(). What do you see?

          This gives me

          QSslSocket(0x4b1e370)
          

          I do not understand why I have a QSslSocket here. I am expecting a `ClientSslSocket' object, because basically, the structure of the code is as follows (I cannot literally copy-paste due to company restrictions):

          bool Foo::initializeSocket(ClientSslSocket* socket)
          {
              ....
              connect(socket, SIGNAL(disconnected()), this, SLOT(disconnectedCallback()));
              ....
          }
          

          If I go up one level in the call stack, then I see that the initializeSocket function gets called as follows:

          ClientSslSocket* socket = new ClientSslSocket();
          if ( initializeSocket(socket)== true )
          { ... }
          

          so for as far as I can see, it gets a pointer to a ClientSslSocket object... I'm puzzled and don't see what I'm overlooking. Could it be something in the implementation of ClientSslSocket that I'm forgetting?

          1 Reply Last reply
          0
          • yeckelY yeckel

            Hi Bart,

            qobject_cast should work as long as everything is QObject inherited. I've tested your code and
            SlientSslSocket* sender2 = qobject_cast<SlientSslSocket*>(sender());
            and it's working (qt 5.5, gcc 4.8.4). I thing there might be problem how is your socket for the method initializeSocket(ClientSslSocket* socket) created. Could you paste longer example?

            B Offline
            B Offline
            Bart_Vandewoestyne
            wrote on last edited by
            #5

            @yeckel Do you have the code of your test-program available somewhere? I would like to test it on my platform...

            yeckelY 1 Reply Last reply
            0
            • B Bart_Vandewoestyne

              @yeckel Do you have the code of your test-program available somewhere? I would like to test it on my platform...

              yeckelY Offline
              yeckelY Offline
              yeckel
              wrote on last edited by
              #6

              @Bart_Vandewoestyne https://drive.google.com/file/d/0B6MSAirH9oMIZi0xNkI5QkFGWnc/view?usp=sharing

              1 Reply Last reply
              0
              • B Offline
                B Offline
                Bart_Vandewoestyne
                wrote on last edited by
                #7

                After some more debugging, I think I figured out the problem. It turns out that the FooBar class has another data structure which also holds pointers to ClientSslSockets, and FooBar's destructor looks as follows:

                FooBar::~FooBar()
                {
                    for (int i = 0; i < theList.size(); ++i)
                    {
                        if (theList.at(i).socket)
                        {
                #ifdef linux
                            theList.at(i).socket->close();
                #else
                            delete TheList.at(i).mpSocket;
                #endif
                            mvConnectionInfoList.at(i).mpSocket = NULL;
                        }
                    }
                }
                

                I'm on Windows, and from what I can debug right now, it seems that the line

                delete TheList.at(i).mpSocket;
                

                is causing the ClientSslSocket destructor being called. And apparently, that same delete statement also triggers the disconnect() signal so that the disconnectedCallback() slot is called, apparently with an already partly destructed sender object (that is my educated guess, I found out that the ClientSslSocket destructor is called before the slot is handled...).

                So I have some more questions now:

                1. Could my educated guess be correct?
                2. Does anybody have any idea why the original author of this code decided to make a difference between linux and non-linux? If I remove the ifdef and simply use close() in all situations, things seem to work, although it seems that in this case the ClientSslSocket destructor is no longer called (and I'm not sure if this is a good thing...).
                3. What would be the clean solution here? How should FooBar's destructor look like?

                Thanks for bearing with me ;-)
                Bart

                JKSHJ 1 Reply Last reply
                0
                • B Bart_Vandewoestyne

                  After some more debugging, I think I figured out the problem. It turns out that the FooBar class has another data structure which also holds pointers to ClientSslSockets, and FooBar's destructor looks as follows:

                  FooBar::~FooBar()
                  {
                      for (int i = 0; i < theList.size(); ++i)
                      {
                          if (theList.at(i).socket)
                          {
                  #ifdef linux
                              theList.at(i).socket->close();
                  #else
                              delete TheList.at(i).mpSocket;
                  #endif
                              mvConnectionInfoList.at(i).mpSocket = NULL;
                          }
                      }
                  }
                  

                  I'm on Windows, and from what I can debug right now, it seems that the line

                  delete TheList.at(i).mpSocket;
                  

                  is causing the ClientSslSocket destructor being called. And apparently, that same delete statement also triggers the disconnect() signal so that the disconnectedCallback() slot is called, apparently with an already partly destructed sender object (that is my educated guess, I found out that the ClientSslSocket destructor is called before the slot is handled...).

                  So I have some more questions now:

                  1. Could my educated guess be correct?
                  2. Does anybody have any idea why the original author of this code decided to make a difference between linux and non-linux? If I remove the ifdef and simply use close() in all situations, things seem to work, although it seems that in this case the ClientSslSocket destructor is no longer called (and I'm not sure if this is a good thing...).
                  3. What would be the clean solution here? How should FooBar's destructor look like?

                  Thanks for bearing with me ;-)
                  Bart

                  JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by
                  #8

                  @Bart_Vandewoestyne said:

                  1. Could my educated guess be correct?

                  Your guess sounds reasonable to me.

                  1. Does anybody have any idea why the original author of this code decided to make a difference between linux and non-linux? If I remove the ifdef and simply use close() in all situations, things seem to work, although it seems that in this case the ClientSslSocket destructor is no longer called (and I'm not sure if this is a good thing...).

                  Nope, sorry. Are there any comments in the code, or in the commit history? Could you ask the author directly?

                  1. What would be the clean solution here? How should FooBar's destructor look like?

                  It's hard to say without knowing how the rest of the program is designed. Maybe you can manually disconnect the socket before deleting it?

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved