-1

If I take, two objects like that:

firstobject.h:

public slots:
    void h_doSomething(int someint, std::vector<int> somevector, bool somebool); //(int)vector.size(): 80;

firstobject.cpp:

void firstobject::h_doSomething(int someint, std::vector<int> somevector, bool somebool)
{
    emit anotherSignal(someint+4, somebool, somevector);
}

secondobject.h:

public signals:
        void doSomething(int someint, std::vector<int> somevector, bool somebool); //(int)vector.size(): 80;
private:
    std::vector< int > m_somevector;

secondobject.cpp:

void secondobject::basicFunction()
{
    emit doSomething(51, m_somevector, true);
}

Those signal and slot are connected, what is the best optimisation of these slots and signals?

For the slot, I guess it would be:

void h_doSomething(const int &someint, const std::vector<int> &somevector, const bool &somebool) const;

But for the signals I've no idea, I think the vector need to be copied since it's a protected variable.

Ticki
  • 15
  • 3
  • See [this](http://stackoverflow.com/questions/10405739/const-ref-when-sending-signals-in-qt). – LogicStuff Jan 17 '16 at 15:37
  • You can pass the vector as const ref. in the signal, too. protected/private has nothing to with that (and if it had, the compiler would tell you by failing). Passing POD types as int and bool via const ref. makes no sense though. – Frank Osterfeld Jan 17 '16 at 17:08

1 Answers1

0

I'd say always pass complex objects by const reference unless you have a really good reason to do otherwise. For primitive types like int and bool it is usually best to pass them as it is.

What you need to understand is that both signals and slots are just functions. Signals are a bit special in the sense that you don't implement it yourself, MOC does that. But it's still just a function! By using const you avoid unnecessary copying which is a good thing even for shared classes, but is especially good when copying takes a lot of resources, like for vector.

One important thing here is that signal-slot connections come in two flavors: direct and queued ones. For a direct connection signal basically calls all connected slots directly so when you do

emit doSomething(51, m_somevector, true);

it just calls the connected slots and passes parameters to them.

For a queued connections, Qt makes a copy of the parameters, queues them and invokes the slots later in another thread. The copy is made even if you declare pass-by-reference, so that will still work fine.

And that leaves really no reason to pass complex objects by value unless there is a risk that something will happen to the object while the call is in progress. For example, it could be that some slot iterates over the vector and during the iteration calls some method that modifies the vector. That could break the iteration process. But even then you could iterate over a copy inside that method and still pass parameters by reference depending on what you want. Or just redesign the whole thing to avoid such modifications.

Sergei Tachenov
  • 24,345
  • 8
  • 57
  • 73
  • Thank for your clear answer! I can do a direct connection because I will block the GUI with a loading bar while processing and disable every other user input. – Ticki Jan 18 '16 at 20:02
  • @Ticki, that's usually a bad idea. You'll not only block input this way, you'll also block repainting so it'll look like it hung. You could, of course, call `QApplication::processEvents` from time to time to prevent that... or use a dedicated thread and block GUI with a modal dialog or something. Your call. – Sergei Tachenov Jan 19 '16 at 04:32