Переназначить интеллектуальный указатель на функцию без передачи права собственности?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
1
задан Woofas 15 April 2019 в 05:58
поделиться

3 ответа

Вы можете определить функцию conditional_reassign2() для получения std::unique_ptr по ссылке вместо по значению :

void conditional_reassign2(std::unique_ptr<MyClass>& ptr)
{
    if (my_condition)
    {
        ptr = std::make_unique<MyClass>(new_param);
    }
}

Таким образом, функция может напрямую измените передаваемый экземпляр, нет необходимости передавать права собственности.

Предполагая, что ptr является std::unique_ptr<MyClass>, тогда вызов conditional_reassign2() будет в этом случае:

conditional_reassign2(ptr);
0
ответ дан El Profesor 15 April 2019 в 05:58
поделиться

Либо вам нужно передать указатель по ссылке

void conditional_reassign2(std::unique_ptr<MyClass>& ptr) {...}

std::unique_ptr<MyClass> myPtr;
conditional_reassign2(myPtr);

или вернуть указатель, для которого требуется один ход

std::unique_ptr<MyClass> conditional_reassign2(std::unique_ptr<MyClass> ptr) {...}

std::unique_ptr<MyClass> myPtr;
myPtr = conditional_reassign2(std::move(myPtr));

Также вы можете вернуть ptr непосредственно из функции без явно вызывающий ход.

std::unique_ptr<MyClass> conditional_reassign2(std::unique_ptr<MyClass> ptr)
{
    if (my_condition)
        ptr = std::make_unique<MyClass>(new_param);
    return ptr;
}
0
ответ дан Tom Marsland 15 April 2019 в 05:58
поделиться

Ваш первый пример не делает то, что вы намерены делать. Поскольку ptr передается по значению, указатель вызывающего не будет изменен. Поэтому, если my_condition равно true, у вызывающей стороны есть указатель, который указывает на удаленный объект, и адрес, по которому сохраняется вновь созданный объект, теряется после возврата из функции.

Вот ваш первый исправленный пример (теперь аргумент является ссылкой на указатель):

void conditional_reassign((MyClass*)& ptr)
{
    if (my_condition)
    {
        delete ptr;
        ptr = new MyClass(new_param);
    }
}

Чтобы использовать unique_ptr, вы также можете использовать ссылки и ничего не возвращать. Таким образом, нет необходимости иметь дело с std::move

void conditional_reassign2(std::unique_ptr<MyClass>& ptr)
{
    if (my_condition)
    {
        ptr =  std::make_unique<MyClass>(new_param);
    }
}

Вы можете назвать это так:

std::unique_ptr<MyClass> ptr = make_unique<MyClass>(old_param);
conditional_reassign2(ptr);

Или вы можете использовать семантику возврата / перемещения:

std::unique_ptr<MyClass> conditional_reassign(std::unique_ptr<MyClass> ptr)
{
    if (my_condition)
    {
        return std::make_unique<MyClass>(new_param);
    }

    return ptr;
}

И назовите это так:

std::unique_ptr<MyClass> ptr = make_unique<MyClass>(old_param);
ptr = conditional_reassign2(std::move(ptr));
0
ответ дан op414 15 April 2019 в 05:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: