Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Destructor(s) called twice as QList of objects derived from shared classes (such as QString) goes out of scope.
Forum Updated to NodeBB v4.3 + New Features

Destructor(s) called twice as QList of objects derived from shared classes (such as QString) goes out of scope.

Scheduled Pinned Locked Moved General and Desktop
3 Posts 2 Posters 1.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Asm_x64
    wrote on last edited by
    #1

    Platform: Qt5.1.0 (built as a shared library) / Linux Fedora 19 x64

    Hi everybody,

    I wanted to make sure destructors of classes derived from shared classes (such as QString and many more) are called when a QList of them is going out of scope. In this test program they happen to be...twice and I get this output (project file and test program code follow):

    Instantiating three DerivedFromQString classes and appending them to list

    Creating string: First string
    Destroying string: First string
    Creating string: Second string
    Destroying string: Second string
    Creating string: Third string
    Destroying string: Third string
    Destroying string: Third string
    Destroying string: Second string
    Destroying string: First string


    Project file:

    QT += core gui
    CONFIG += qt
    QT += widgets
    CONFIG += release
    TARGET = QList_Test
    TEMPLATE = app
    SOURCES = QList_Test.cpp

    Code:

    @
    #include <iostream>

    #include <QApplication>
    #include <QString>
    #include <QList>

    /*************************************************************************************************************/

    class DerivedFromQString:public QString
    {
    public:

    DerivedFromQString(const char *text):QString(text)
    {
    std::cout << "Creating string: " << text << std::endl;
    }

    ~DerivedFromQString() // Declaring the destructor as virtual does not change anything.
    {
    std::cout << "Destroying string: " << toStdString() << std::endl;
    }
    };

    /*************************************************************************************************************/

    int main(int argc, char **argv)
    {
    QApplication app(argc, argv);

    QList<DerivedFromQString> string_list;

    std::cout << "\nInstantiating three DerivedFromQString classes and appending them to list" << std::endl;

    string_list.append("First string");
    string_list.append("Second string");
    string_list.append("Third string");

    }// string_list goes out of scope. Destructors of its objects are unexpectedly called twice.
    @

    1 Reply Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      That's correct behaviour, because you created two copies of each string.

      The first copy is created when your const char* input is converted into a DerivedFromQString using the constructor that you wrote. The second copy is created when QList::append() clones your value in order to store it, using the (default) copy constructor which doesn't print a message.

      If your compiler supports C++11, you can prevent the copying by specifying a move constructor. (According to "this":http://stackoverflow.com/questions/4819936/why-no-default-move-assignment-move-constructor, you don't get a default move constructor because you specified a non-default destructor.) However, even if you don't have C++11, the copying is still cheap since QString is implicitly shared (a.k.a. copy-on-write).

      [quote]Creating string: First string
      Destroying string: First string
      Creating string: Second string[/quote]Notice that the destructor is called BEFORE the constructor for "Second string" -- The first copy of "First string" went out of scope when string_list.append("First string") returned.

      By the way, instead of std::cout, you can use qDebug()

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Asm_x64
        wrote on last edited by
        #3

        Thanks for your enlightening comments.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved