From 90a68926f311ac5bb8f7c53ac8370f9ff7f12c08 Mon Sep 17 00:00:00 2001 From: Roman Pasechnik Date: Tue, 2 Jul 2013 21:35:21 +0300 Subject: Add QEnableSharedFromThis class It enables you to get a valid QSharedPointer instance to 'this', when all you have is 'this'. Task-number: QTBUG-7287 Change-Id: I3ed1c9c4d6b110fe02302312cc3c4a75e9d95a0c Reviewed-by: Richard J. Moore --- .../tools/qsharedpointer/tst_qsharedpointer.cpp | 223 +++++++++++++++++++++ 1 file changed, 223 insertions(+) (limited to 'tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp') diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index 9bcce60e93..ac37b9af2a 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -112,6 +112,7 @@ private slots: void invalidConstructs(); void qvariantCast(); + void sharedFromThis(); public slots: void cleanup() { safetyCheck(); } @@ -2141,6 +2142,228 @@ void tst_QSharedPointer::qvariantCast() } } +class SomeClass : public QEnableSharedFromThis +{ +public: + SomeClass() + { + } + + QSharedPointer getSharedPtr() + { + return sharedFromThis(); + } + + QSharedPointer getSharedPtr() const + { + return sharedFromThis(); + } + + Data data; +}; + +void tst_QSharedPointer::sharedFromThis() +{ + const int generations = Data::generationCounter; + const int destructions = Data::destructorCounter; + + { + SomeClass sc; + QSharedPointer scp = sc.sharedFromThis(); + QVERIFY(scp.isNull()); + QCOMPARE(Data::generationCounter, generations + 1); + QCOMPARE(Data::destructorCounter, destructions); + + QSharedPointer const_scp = sc.sharedFromThis(); + QVERIFY(const_scp.isNull()); + QCOMPARE(Data::generationCounter, generations + 1); + QCOMPARE(Data::destructorCounter, destructions); + } + + QCOMPARE(Data::generationCounter, generations + 1); + QCOMPARE(Data::destructorCounter, destructions + 1); + + { + const SomeClass sc; + QSharedPointer const_scp = sc.sharedFromThis(); + QVERIFY(const_scp.isNull()); + QCOMPARE(Data::generationCounter, generations + 2); + QCOMPARE(Data::destructorCounter, destructions + 1); + } + + QCOMPARE(Data::generationCounter, generations + 2); + QCOMPARE(Data::destructorCounter, destructions + 2); + + { + SomeClass *sc = new SomeClass; + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + QSharedPointer scp; + QVERIFY(scp.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp = sc->sharedFromThis(); + QVERIFY(scp.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp = QSharedPointer(sc); + QVERIFY(!scp.isNull()); + QCOMPARE(scp.data(), sc); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + QSharedPointer scp2; + QVERIFY(scp2.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp2 = sc->sharedFromThis(); + QVERIFY(!scp2.isNull()); + QVERIFY(scp == scp2); + QCOMPARE(scp2.data(), sc); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + QSharedPointer scp3; + QVERIFY(scp3.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp3 = sc->sharedFromThis(); + QVERIFY(!scp3.isNull()); + QVERIFY(scp == scp3); + QVERIFY(scp2 == scp3); + QCOMPARE(scp3.data(), sc); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + QSharedPointer scp4; + QVERIFY(scp4.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp4 = sc->getSharedPtr(); + QVERIFY(!scp4.isNull()); + QVERIFY(scp == scp4); + QVERIFY(scp2 == scp4); + QVERIFY(scp3 == scp4); + QCOMPARE(scp4.data(), sc); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + QSharedPointer scp5; + QVERIFY(scp5.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp5 = const_cast(sc)->getSharedPtr(); + QVERIFY(!scp4.isNull()); + QVERIFY(scp == scp5); + QVERIFY(scp2 == scp5); + QVERIFY(scp3 == scp5); + QVERIFY(scp4 == scp5); + QCOMPARE(scp5.data(), sc); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + } + + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 3); + + QSharedPointer scp; + + QVERIFY(scp.isNull()); + + { + QSharedPointer scp2(new SomeClass()); + QVERIFY(!scp2.isNull()); + + scp = scp2->sharedFromThis(); + QVERIFY(!scp.isNull()); + + QVERIFY(scp == scp2); + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + } + + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + + { + QSharedPointer scp2; + scp2 = scp->sharedFromThis(); + QVERIFY(!scp2.isNull()); + + QVERIFY(scp == scp2); + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + } + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + + { + QSharedPointer scp2; + scp2 = scp->getSharedPtr(); + QVERIFY(!scp2.isNull()); + + QVERIFY(scp == scp2); + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + } + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + + { + QSharedPointer scp2; + scp2 = qSharedPointerConstCast(scp)->getSharedPtr(); + QVERIFY(!scp2.isNull()); + + QVERIFY(scp == scp2); + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + } + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + + { + QSharedPointer scp2; + scp2 = scp->sharedFromThis(); + QVERIFY(!scp2.isNull()); + + QVERIFY(scp == scp2); + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + + scp2.clear(); + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + QVERIFY(scp2.isNull()); + } + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + + scp.clear(); + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 4); + +} + namespace ReentrancyWhileDestructing { struct IB { -- cgit v1.2.3