Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
366 views
in Technique[技术] by (71.8m points)

c++ - Not able to return a unique_ptr from a class member function

I'm unable to return a unique_ptr from a class member fuction, while implementing the Builder Design Pattern. As part of the builder design pattern, I want to create an object using the builder and transfer the ownership of the smart pointer to the client code. However, as I understand from the compilation error, I see that there is some problem in returing a unique_ptr from a class member function.

// Progarm to demonstrate builder design pattern.
#include <iostream>
#include <memory>

class person 
{
    std::string name_ {};
    uint8_t age_ = 0;
    std::string uniqueId_ {};

    person(std::string name):name_(name) {

    }
public:
    // Person Builder
    class personBuilder;

    // Public member function to print his info.
    void displayPersonInfo()
    {
        std::cerr << "
Name:" << name_
                    << "
Age:" << std::to_string(age_)
                    << "
UniqueId:" << uniqueId_
                    << "
";
    }

    // Destructor
    virtual ~person()
    {
        std::cerr << "
Destroy Person Object
";
    }
};

class person::personBuilder
{
    std::unique_ptr<person> pThePerson;

public:
    personBuilder(std::string name)
    {
        pThePerson = std::make_unique<person>(name);
    }

    personBuilder & age(const uint8_t age)
    {
        pThePerson->age_ = age;
        return *this;
    }

    personBuilder & uniqueId(const std::string uniqueId)
    {
        pThePerson->uniqueId_ = uniqueId;
        return *this;
    }

    std::unique_ptr<person> build()
    {
        return pThePerson;
    }
};

int main(int argc, char** argv)
{
    std::unique_ptr<person> myPerson = person::personBuilder("Sachin Tendulkar")
                    .age(40).uniqueId("AABBCC").build();

    myPerson->displayPersonInfo();

    return 0;
}

The following is the compilation error that I'm getting.

$ g++ 04_builder_02_short.cpp
04_builder_02_short.cpp: In member function ‘std::unique_ptr<person> person::personBuilder::build()’:
04_builder_02_short.cpp:58:16: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = person; _Dp = std::default_delete<person>]’
         return pThePerson;
                ^~~~~~~~~~
In file included from /usr/include/c++/8/memory:80,
                 from 04_builder_02_short.cpp:3:
/usr/include/c++/8/bits/unique_ptr.h:397:7: note: declared here
       unique_ptr(const unique_ptr&) = delete;
       ^~~~~~~~~~
/usr/include/c++/8/bits/unique_ptr.h: In instantiation of ‘typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = person; _Args = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<person>]’:
04_builder_02_short.cpp:41:51:   required from here
/usr/include/c++/8/bits/unique_ptr.h:835:30: error: ‘person::person(std::__cxx11::string)’ is private within this context
     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
04_builder_02_short.cpp:11:5: note: declared private here
     person(std::string name):name_(name) {
     ^~~~~~
$
question from:https://stackoverflow.com/questions/65932599/not-able-to-return-a-unique-ptr-from-a-class-member-function

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

unique_ptr is sole ownership object it means its copy constructor and assignment operators are deleted. So you can not copy. Sole ownership objects can just be moved. You can return unique_ptr by `

return std::move(unique_ptr);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...