0

In Qt, most classes usually have a public wrapper class with a single pointer to a private class. This is for binary compatibility.

https://wiki.qt.io/D-Pointer

However this means that there are a lot of things that need to be implemented by hand. Some people suggest using a QScopedPointer.

How to use the Qt's PIMPL idiom?

However, this does not implement copy and assignment either. Isn't there a smart pointer that will just copy the content of the pointer when it's copied. In essence, it should behaves as if the data in the private class were in the public class.

ymoreau
  • 2,768
  • 1
  • 15
  • 42
yokto
  • 725
  • 4
  • 18

2 Answers2

3

Qt offers a class just for this purpose: QSharedDataPointer

Used with QSharedData it offers a fast way to implement a class with implicitly shared data and copy on write behavior.

You can also do explicit sharing with QExplicitlySharedDataPointer.

class MyData : public QSharedData
{
  public:
    MyData (){ }
    MyData (const MyData &other)
        : QSharedData(other), a(other.a), b(other.b) { }
    ~MyData () { }

    int a;
    QString b;
};

class MyClass
{
  public:
    MyClass() { d = new MyData; }
    MyClass(const MyClass&other)
          : d (other.d)
    {
    }
    void setA(int a) { d->a = a; } // the function is non const, so accessing d->a will make a copy of MyData if d is shared with another instance (CoW)
    int a() const { return d->a; }

  private:
    QSharedDataPointer<MyData> d;
};
Benjamin T
  • 7,359
  • 17
  • 31
1

The QScopePointer is the equivalent of the std::unique_ptr, it's a pointer with unique ownership, meaning that it can not be copied.

What usually you do is a deep copy of what the ScopedPointer is pointing to when you implement the copy operation of the facade.

Another solution is to have the pimpl implemented with a shared pointer (QSharedPointer) ; but that means that a facade copied from another will point point to the same pimpl. In some scenarios that can be relevant.

sandwood
  • 1,768
  • 14
  • 29