3

How can I pass a QScopedPointer object to another function like that:

bool addChild(QScopedPointer<TreeNodeInterface> content){
   TreeNode* node = new TreeNode(content);
}

TreeNode:

TreeNode::TreeNode(QScopedPointer<TreeNodeInterface> content)
{
    mContent.reset(content.take());
}

I get: error: 'QScopedPointer::QScopedPointer(const QScopedPointer&) [with T = TreeNodeInterface; Cleanup = QScopedPointerDeleter]' is private

How can I solve it? Thanks!

yonutix
  • 1,964
  • 1
  • 22
  • 51
  • 2
    `QScopedPointer` is designed to be non-copyable. Why do you need this? – Pavel Strakhov May 14 '15 at 13:57
  • I need this in order to pass a unique pointer to a specific class without using a raw pointer, I just want to move it from method to method – yonutix May 14 '15 at 13:59
  • 3
    Since QSharedPointer is neither copyable nor movable, you cannot achieve the desired functionality. However, you could use a std::unique_ptr, which is movable and use std::move to move the ownership of the pointer to the TreeNode. – Robert May 14 '15 at 14:04

1 Answers1

3

You can do it by accepting a reference to the pointer - that way you can swap the null local pointer with the one that was passed to you:

#include <QScopedPointer>
#include <QDebug>

class T {
   Q_DISABLE_COPY(T)
public:
   T() { qDebug() << "Constructed" << this; }
   ~T() { qDebug() << "Destructed" << this; }
   void act() { qDebug() << "Acting on" << this; }
};

void foo(QScopedPointer<T> & p)
{
   using std::swap;
   QScopedPointer<T> local;
   swap(local, p);
   local->act();
}

int main()
{
   QScopedPointer<T> p(new T);
   foo(p);
   qDebug() << "foo has returned";
   return 0;
}

Output:

Constructed 0x7ff5e9c00220 
Acting on 0x7ff5e9c00220 
Destructed 0x7ff5e9c00220 
foo has returned
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • The problem with this solution that the passed scoped pointer should not be used after that `foo()` has been called: it highly depends on the implementation whether it has been changed (or reset to `nullptr`) and this causes undefined behaviour. moving is required here, which makes explicit the invalidation of the pointer. Althought move semantic was implemented for QScopedPointer, but it has been revoked because it was not "scoped". So `std::unique_ptr` should be used. – titapo Jun 01 '17 at 07:47
  • 1
    There's absolutely no ifs nor buts about the behavior of swap with any sort of a unique owning pointer: if you swap a default-constructed pointer with one that holds some data, then after `foo` returns, `p` is a default-constructed pointer. There's no undefined behavior, and there can't be otherwise `swap` would be useless. And of course you should be using `std::unique_ptr` instead - I agree. – Kuba hasn't forgotten Monica Jun 01 '17 at 13:16