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();
}