I am working on some code where I see the following:
In header file:
private slot:
void OnNotifySomeSlot(const QList<bool>& someList); // Note the argument is pass by const ref
In implementation file:
connect(&m_serviceObj,SIGNAL(NotifySomeSlot(QList<bool>)), this, SLOT(OnNotifySomeSlot(QList<bool>)); // Note that arguments are pass by value
Slot function definition:
void OnNotifySomeSlot(const QList<bool>& someList)
{
m_list = someList;
} // Note that argument is passed by const ref as in the header
Now my doubt is that:
1: Why is such a code getting compiled as there is difference in signature between connect statement and slot definition?
2: During runtime if the value is getting passed a const ref , will it still not cause problems in a multithreaded environment. Because the reference to the list (be it const) can still be modified by some other code referring the same list in a multithreaded environment.
3: Can we just "pass by value" everywhere to avoid any issue in a multi threaded environment. Will it make the application slower?
CodePudding user response:
Answering your questions in order:
- The Qt macro machinery canonicalizes signal and slot names so they "fit". If you use the modern connection approach you do not have to worry about this:
QObject::connect(m_serviceObj, &SomeServiceObjectClass::NotifySomeSlot, this, &ThisObjectClassOnNotifySomeSlot)
- Yes, even though you pass the list as a const ref, some other thread that has a non-const ref can change it behind your back.
- Yes, passing it by value makes this behave properly. It is also efficient, as QList is an "implicitly shared" datastructure. This means that a copy is only made when a mutation happens, by the thread doing the mutation.