mercredi 2 décembre 2020

How can a class be made (partial) owner of a pointer given a function that returns a unique_ptr

This question is a follow-up to Why doesn't returning a std::unique_ptr violate unique_ptr's deleted copy constructor? (which is answered here: Returning unique_ptr from functions )

This leads me back to the original problem I'd faced.

I have to work with a function (outside my control) that returns a std::unique_ptr. I would like instances of a class to have a reference to the object the unique_ptr encapsulates, but I'm unclear and fumbling with the syntax of what's needed to pull this off.

I hope this sample code makes my intent clear, given that I can't find the right model/syntax to make this compile: I'd like instances of class PtrOwner to be able to "own" some form of reference to the underlying object encapsulated by the unique_ptr that is returned by function getUniquePtr():

// main.cpp
#include <memory>
#include <iostream>

std::unique_ptr<int> getUniquePtr() {
  return std::unique_ptr<int>(new int( 42 ));
}

class PtrOwner {
  std::unique_ptr<int> p_;

public:
  PtrOwner( std::unique_ptr<int> p ) : p_(p) {}
};

int main( int argc, char* argv[] ) {
  PtrOwner po( getUniquePtr() );

  return 0;
}
$ g++ --version && g++ -g ./main.cpp && ./a.out
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

./main.cpp: In constructor ‘PtrOwner::PtrOwner(std::unique_ptr<int>)’:
./main.cpp:13:44: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
   PtrOwner( std::unique_ptr<int> p ) : p_(p) {}
                                            ^
In file included from /usr/include/c++/6/memory:81:0,
                 from ./main.cpp:2:
/usr/include/c++/6/bits/unique_ptr.h:359:7: note: declared here
       unique_ptr(const unique_ptr&) = delete;
       ^~~~~~~~~~

What is good practice/accepted convention to pull this off? I tried fumbling with the concept of PtrOwner owning a shared_ptr but I'm not adept with that class either, and couldn't pull off the required syntax:

// main.cpp
#include <memory>
#include <iostream>

std::unique_ptr<int> getUniquePtr() {
  return std::unique_ptr<int>(new int( 42 ));
}

class PtrOwner {
  std::shared_ptr<int> p_;

public:
  PtrOwner( const std::unique_ptr<int>& p ) : p_(p) {}
};

int main( int argc, char* argv[] ) {
  PtrOwner po( getUniquePtr() );

  return 0;
}

(I think the error from the second code block is too spammy for me to reasonably post here)

Aucun commentaire:

Enregistrer un commentaire