/*! * \brief Qt5's signal and slot connection, using pointer to member functions. */ void ConnectLambdaTest::testCaseNormalUse() { // create sender and receiver objects QScopedPointer<Object> sender ( new Object ); QScopedPointer<Object> receiver ( new Object ); // connect them connect(sender.data(), &Object::signalTest, receiver.data(), &Object::slotTest); // emit signal sender->emitSignal(0x58ef); // test if slot correclty receive info QCOMPARE(0x58ef, receiver->checkValue()); }
/*! * \brief Use lambda with Qt5's new connection syntaxe. */ void ConnectLambdaTest::testCaseWithLambda() { // create sender and receiver objects // receiver is shared with lambda context QScopedPointer<Object> sender ( new Object ); QSharedPointer<Object> receiver ( new Object ); // connect them with lambda connect(sender.data(), &Object::signalTest, [receiver](int value){ Q_ASSERT(receiver); receiver->setCheckValue(value); }); // emit signal sender->emitSignal(0xb69d); // test if slot correclty receive info QCOMPARE(0xb69d, receiver->checkValue()); }
/*! * \brief Use QPointer to check pointer in lambda. * QPointer is Qt's smart pointer, which become nullptr when * QObject's derived object is deleted. QPointer is copiable, * then when can copy it directly inside lambda. * * In lambda, we can just check pointer with assert, if the receiver * can have a shorter lifetime than sender, or 'if' statement if * receiver need to have a longer lifetime than sender. */ void ConnectLambdaTest::testCaseLambdaQPointer() { // create sender and receiver objects // use QPointer to check pointer before use QScopedPointer<Object> sender ( new Object ); QPointer<Object> receiver ( new Object ); // connect them with lambda connect(sender.data(), &Object::signalTest, [receiver](int value){ Q_ASSERT(receiver); receiver->setCheckValue(value); }); // delete receiver delete receiver; // emit signal sender->emitSignal(0x800a); // can't test, receiver is nullptr // QCOMPARE(0x800a, receiver->checkValue()); QFAIL("This test need to fail..."); }
/*! * \brief Use lambda with Qt5's new connection syntaxe, with invalide pointer. * The raw pointer become invlide inside the lambda, but the connect is not * destroy when receiver is deleted. Then, emitting signal call lambda * with this invalid pointer, and cause a Undefined Behavior (UB). * * Note: UB doesn't cause crash every time. When I run this tests (MingW 4.9.2 * and MSVC 2013), the test run like object is valid. */ void ConnectLambdaTest::testCaseLambdaAndDeletedObject() { // create sender and receiver objects // we want to delete receiver before end of function, the use raw pointer QScopedPointer<Object> sender ( new Object ); Object* receiver ( new Object ); // connect them with lambda connect(sender.data(), &Object::signalTest, [receiver](int value){ Q_ASSERT(receiver); receiver->setCheckValue(value); }); // delete receiver delete receiver; receiver = nullptr; // emit signal sender->emitSignal(0x2d9b); // can't test, receiver is nullptr // QCOMPARE(0x800a, receiver->checkValue()); QFAIL("This test need to fail..."); }