Qt QSharedDataPointer and QSharedData how to know who is sharing the pointer?

Viewed 28

I have searched, but I am unsure if the solution I found make sense.

Problem: I have a Song Library and want to make Playlists that have some Songs of that Library. And, in the best case, do not occupy the memory more than once.

Solution: Pointers to a Song class. I came across a QSharedDataPointer with QSharedData as a possible solution. Although, I am still wondering if this is a little too much of an effort for the result.

In the example the Songs have just an Id and Name and a reference to the List they are in. If a Song (pointer) is added to another List, the List has to be added to the shared Data manually. Can I make it automatically?

Is this approach a reasonable one? Or am I completely off track? ;)

The Example from Qt: https://doc.qt.io/qt-5/qshareddatapointer.html Another similar Question (and a Solution I do not understand): https://www.qtcentre.org/threads/23070-QSharedPointer-How-to-get-information-about-who-is-sharing-the-pointer

#include <QCoreApplication>
#include <QSharedData>
#include <QExplicitlySharedDataPointer>

class Song; // frwd ref.

class SongData : public QSharedData
{
public:
    SongData() : id(-1) { }
//  Copy Constr not needed here
//    SongData(const SongData &other)
//        : QSharedData(other), id(other.id), name(other.name) {}
    ~SongData(){ qInfo()<< "deconstructed" << this->ref << this->name;}

    QList<QList<Song*>*> pointerList;
    int id;
    QString name;

};

class Song
{
public:
    Song(){s = new SongData;}
    Song(int id, const QString &name, QList<Song*> *list) {
        s = new SongData;
        setId(id);
        setName(name);
        addToList(list);
    }
//  Copy Constr not needed here
//    Song(const Song &other)
//          : s (other.s)
//    {
//    }
    void setId(int id) {s->id = id;}
    void setName(const QString &name){s->name = name;}
    void addToList(QList<Song*> *list){s->pointerList.append(list);}

    int id() const {return s->id;}
    QString name() const {return s->name;}
    QList<QList<Song*>*> song() const {return s->pointerList;}

private:
    QExplicitlySharedDataPointer<SongData> s;

};

Q_DECLARE_TYPEINFO(Song, Q_MOVABLE_TYPE);


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // Create 3 Songs
    QList<Song*> *songList = new QList<Song*>;

    songList->append(new Song(1, "first Song", songList));
    songList->append(new Song(2, "second Song", songList));
    songList->append(new Song(3, "third Song", songList));

    qInfo() << "Members:" << songList->size() << "IDs:" << songList->at(0)->id()<< songList->at(1)->id()<< songList->at(2)->id();

    QList<Song*> *songList2 = new QList<Song*>;
    songList2->append(songList->data()[0]); //or: songList2->append(songList->at(0));
    songList2->data()[songList2->size()-1]->addToList(songList2);

    songList->data()[0]->setName("Changed");

    qInfo() << "SongList" << songList->at(0)->id() << songList->at(0)->name() << &songList->data()[0];
    qInfo() << "SongList2" << songList2->at(0)->id() << songList2->at(0)->name() << &songList->data()[0];
    // same: qInfo() << "true save" << &songList->data()[0] << &songList2->data()[0];

    qInfo() << "How many Times a song is in a List:";
    qInfo() << songList->at(0)->song().size();
    qInfo() << songList->at(1)->song().size();
    qInfo() << songList->at(2)->song().size();

    qInfo() << songList->data()[0]->song();      // The shared data indeed holds the two Lists.
    qInfo() << songList << songList2;

    return a.exec();
}
0 Answers
Related