mercredi 27 janvier 2021

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 << "\nName:" << name_
                    << "\nAge:" << std::to_string(age_)
                    << "\nUniqueId:" << uniqueId_
                    << "\n";
    }

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

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) {
     ^~~~~~
$

Aucun commentaire:

Enregistrer un commentaire