Search code examples
c++qtqsharedpointer

Attaching signals and slots to an object within a QSharedPointer


My application contained several functions like this:

void SomeClass::set_data_provider(DataProvider *data_provider)
{
    connect(data_provider, SIGNAL(data_available(int)),
        this, SLOT(data_available(int)));
}

To avoid passing raw pointers around I have changed all occurrences of DataProvider * to QSharedPointer<DataProvider>. The latter is almost a drop-in replacement for the former, except that you can’t pass a QSharedPointer to QObject::connect. I worked around this by extracting a raw pointer from the QSharedPointer:

void SomeClass::set_data_provider(QSharedPointer<DataProvider> data_provider)
{
    connect(data_provider.data(), SIGNAL(data_available(int)),
        this, SLOT(data_available(int)));
}

This seems to work fine but it looks inelegant and I’m wary of accessing the raw pointer like this. Is there a better way to connect to an object that’s being passed around in a QSharedPointer?


Solution

  • You can create a custom connect function:

    template<class T> bool
    my_connect(const QSharedPointer<T> &sender,
               const char *signal,
               const QObject *receiver,
               const char *method,
               Qt::ConnectionType type = Qt::AutoConnection)
    {
        return QObject::connect(sender.data(), signal, receiver, method, type);
    }
    

    And use it like this:

    QSharedPointer<MyObject> shared(new MyObject);
    my_connect(shared, SIGNAL(my_signal()), this, SLOT(my_slot()));
    

    The only problem is that in both yours and mine solutions you will lose Qt Creator autocomplete for the native connect function.

    P.S. As for me, I wouldn't change your code. I think it's fine :)