I had to implement a copy operator for a class which contains a QSharedDataPointer to the private data. Which is working, but only as long as I do not delete one of the copies. Other than expected it seems that the reference counter is not increased by copying the pointer.
main.cpp:
#include <QtDebug>
#include "Nix.h"
int main( int , char ** )
{
Nix *nix1 = new Nix(1, "Hello, I'm one");
Nix *nix2 = new Nix();
nix2 = nix1;
nix2->add(2, "Hello, I'm two");
Nix *nix3 = new Nix(*nix2);
nix3->add(3, "Hello, I'm three");
qWarning() << "nix1: " << nix2->display(1) << nix1->display(2) << nix1->display(3);
qWarning() << "nix2: " << nix2->display(1) << nix2->display(2) << nix1->display(3);
delete nix2; // if nix1 is deleted, accessing nix2 will produce a segment violation
qWarning() << "nix3: " << nix3->display(1) << nix3->display(2) << nix3->display(3);
// segmentation fault:
qWarning() << "nix1: " << nix1->display(1) << nix1->display(2) << nix1->display(3);
return 0;
}
Nix.h:
#include <QString>
#include <QSharedDataPointer>
class NixPrivate;
class Nix
{
public:
Nix();
Nix(int a, QString b);
~Nix();
Nix(Nix const &other);
Nix &operator=(const Nix &other);
QString display(int x);
void add(int a, QString b);
private:
QSharedDataPointer<NixPrivate> d;
};
Nix.cpp
#include "Nix.h"
#include <QMap>
#include <QString>
#include <QSharedData>
class NixPrivate : public QSharedData
{
public:
QMap<int, QString> myMap;
};
Nix::Nix()
: d(new NixPrivate())
{
}
Nix::Nix(int a, QString b)
: Nix()
{
d->myMap[a] = b;
}
Nix::~Nix()
{
}
Nix::Nix(Nix const &other)
: Nix()
{
d = other.d;
}
Nix &Nix::operator=(const Nix &other)
{
d = other.d;
return *this;
}
QString Nix::display(int x)
{
if (d->myMap.contains(x))
{
return d->myMap.value(x);
}
else
{
return "not found";
}
}
void Nix::add(int a, QString b)
{
d->myMap[a] = b;
}
it seems, that the move assignment operator is called:
QSharedDataPointer<T> &QSharedDataPointer::operator=(QSharedDataPointer<T> &&other)
If the documentation is right, I would need the other one:
QSharedDataPointer<T> &QSharedDataPointer::operator=(const QSharedDataPointer<T> &o)
I've tried to use a cast statement, but with no success.
I had to implement a copy operator for a class which contains a QSharedDataPointer to the private data. Which is working, but only as long as I do not delete one of the copies. Other than expected it seems that the reference counter is not increased by copying the pointer.
main.cpp:
#include <QtDebug>
#include "Nix.h"
int main( int , char ** )
{
Nix *nix1 = new Nix(1, "Hello, I'm one");
Nix *nix2 = new Nix();
nix2 = nix1;
nix2->add(2, "Hello, I'm two");
Nix *nix3 = new Nix(*nix2);
nix3->add(3, "Hello, I'm three");
qWarning() << "nix1: " << nix2->display(1) << nix1->display(2) << nix1->display(3);
qWarning() << "nix2: " << nix2->display(1) << nix2->display(2) << nix1->display(3);
delete nix2; // if nix1 is deleted, accessing nix2 will produce a segment violation
qWarning() << "nix3: " << nix3->display(1) << nix3->display(2) << nix3->display(3);
// segmentation fault:
qWarning() << "nix1: " << nix1->display(1) << nix1->display(2) << nix1->display(3);
return 0;
}
Nix.h:
#include <QString>
#include <QSharedDataPointer>
class NixPrivate;
class Nix
{
public:
Nix();
Nix(int a, QString b);
~Nix();
Nix(Nix const &other);
Nix &operator=(const Nix &other);
QString display(int x);
void add(int a, QString b);
private:
QSharedDataPointer<NixPrivate> d;
};
Nix.cpp
#include "Nix.h"
#include <QMap>
#include <QString>
#include <QSharedData>
class NixPrivate : public QSharedData
{
public:
QMap<int, QString> myMap;
};
Nix::Nix()
: d(new NixPrivate())
{
}
Nix::Nix(int a, QString b)
: Nix()
{
d->myMap[a] = b;
}
Nix::~Nix()
{
}
Nix::Nix(Nix const &other)
: Nix()
{
d = other.d;
}
Nix &Nix::operator=(const Nix &other)
{
d = other.d;
return *this;
}
QString Nix::display(int x)
{
if (d->myMap.contains(x))
{
return d->myMap.value(x);
}
else
{
return "not found";
}
}
void Nix::add(int a, QString b)
{
d->myMap[a] = b;
}
it seems, that the move assignment operator is called:
QSharedDataPointer<T> &QSharedDataPointer::operator=(QSharedDataPointer<T> &&other)
If the documentation is right, I would need the other one:
QSharedDataPointer<T> &QSharedDataPointer::operator=(const QSharedDataPointer<T> &o)
I've tried to use a cast statement, but with no success.
Share Improve this question edited Feb 7 at 7:11 Jodeli asked Feb 6 at 13:55 JodeliJodeli 113 bronze badges 01 Answer
Reset to default 1This is just replacing a pointer with another pointer.
nix1 = nix2
That was a total thinking failure. What I actually wanted to test was something like that:
{
Nix nix4(4, "Hello, I'm four");
*nix1 = nix4;
}
qWarning() << "nix1: " << nix1->display(4);
And that works.
solved, actually with help from SGaist (qt.forum)