Как превратить this в std :: unique_ptr? - PullRequest
0 голосов
/ 08 мая 2020

Как в следующем коде вернуть тот же объект из функции Object::get ниже. Пожалуйста, посмотрите комментарии в этой функции.

Функция возвращает std::unique_ptr нового Object с заданным id. Но если id совпадает с id объекта или если id объекта было установлено на error, тогда должен быть возвращен указатель this (то есть тот же объект). Итак, как мне вернуть тот же объект из функции Object::get?

#include <set>
#include <memory>
#include <iostream>

class IObject
{
public:
    virtual std::unique_ptr<IObject> get(std::string id) = 0;
    virtual void fun() = 0;

    virtual ~IObject() {}
};

class Object : virtual public IObject
{
public:
    Object(std::string id) : id_(id) {}

    virtual std::unique_ptr<IObject> get(std::string i)
    {
        if((id() == i) || (id() == "error")) {
            // Return the same object
            //return this; // How to achieve this? How to return the same object?
            return std::make_unique<Object>(id()); // This does not return the same object.
        }

        if(ids.end() == ids.find(i)) {
            return std::make_unique<Object>("error");
        }

        return std::make_unique<Object>(i);
    }

    virtual void fun()
    {
        std::cout << "Object is: " << id() << std::endl;
    }

    std::string const& id() const
    {
        return id_;
    }

private:
    static std::set<std::string> const ids;

    std::string id_;
};

std::set<std::string> const Object::ids{"id0", "id1", "id2", "id3"};


int main()
{
    auto o = std::make_unique<Object>("id0");
    o->get("id1")->get("id2")->get("id3")->fun();
    o->get("id1")->get("idN")->get("id2")->fun();
    o->get("id1")->get("idN")->get("id2")->get("id3")->fun();
    o->get("id1")->get("id2")->get("id2")->fun();
    o->get("id1")->get("id2")->get("id2")->get("id3")->fun();

    return 0;
}

Ответы [ 2 ]

0 голосов
/ 08 мая 2020

Ответ на ваш вопрос прост.

    return std::unique_ptr<Object>(this);

Однако, как указал Никол в своем ответе, это почти наверняка НЕ ​​то, что вам нужно.

Рассмотрим следующий код:

Object foo("foo");
foo.get();

Бум! Вы только что вызвали free для некоторой памяти, которая не была выделена в куче

0 голосов
/ 08 мая 2020

A unique_ptr представляет уникальное право собственности на объект. Тип разработан таким образом, что существует ровно и только один unique_ptr, который управляет временем жизни этого объекта; поэтому он называется «уникальным».

Следовательно, если кто-то уже имеет уникальное право собственности на объект this, вы не можете передать кому-то еще уникальное право собственности на него. Потому что тогда это не будет уникальное владение. Вы даже не можете дать текущему владельцу уникальное право собственности на this, потому что тогда они будут владеть им в двух местах.

То, что вы хотите, не является разумным поступком. Вы либо намереваетесь использовать семантику совместного владения (и, следовательно, должны использовать shared_ptr или какой-либо эквивалент, который имеет enable_shared_from_this), либо вы не хотите, чтобы функция возвращала unique_ptr.

...