Shared_from_this () экземпляра, который еще не принадлежит shared_ptr, всегда возвращает null?

Я пытаюсь создать функцию-член, которая возвращает, сохранено ли оно в shared_ptr.

class X : public std::enable_shared_from_this {
    ...
    bool is_shared() const {
        return shared_from_this();
    }
};

...

(new X())->is_shared(); // -> false?

Это законно? В этом случае гарантированно ли shared_from_this () вернет null и не вызовет никаких исключений?

en.cppreference.com/w/cpp/memory/enable_shared_from_this/…
StoryTeller - Unslander Monica 02.05.2018 15:17

Из en.cppreference.com/w/cpp/memory/enable_shared_from_this/…: "Разрешено вызывать shared_from_this только для ранее совместно используемого объекта, то есть для объекта, управляемого std :: shared_ptr. В противном случае поведение не определено (до C++ 17) std :: bad_weak_ptr выбрасывается (конструктором shared_ptr из по умолчанию weak_this) (начиная с C++ 17) ". Это зависит от того, какую версию C++ вы используете.

François Andrieux 02.05.2018 15:18

Я не уверен, что shared_from_this вообще может вернуть nullptr в четко определенной программе.

François Andrieux 02.05.2018 15:19

@ FrançoisAndrieux Спасибо. Я читал руководство на основе C++ 11, но в нем ничего не говорится об этом случае.

mtyk1 02.05.2018 15:26
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
754
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

shared_from_this можно использовать для получения shared_ptr от объекта, которым уже управляет shared_ptr.

Вызов shared_from_this для необщего объекта является неопределенным поведением в C++ 11.

Однако в C++ 17 shared_from_this выдаст bad_weak_ptr, и вы можете поймать это исключение:

#include <memory>
#include <iostream>

class X : public std::enable_shared_from_this<X> {
  public:
    bool is_shared() const {
        try {
            shared_from_this();
            return true;
        } catch (std::bad_weak_ptr&) {
            return false;
        }
    }
};

int main() {
    X x;
    std::cout << std::boolalpha << x.is_shared() << std::endl;
    auto y = std::make_shared<X>();
    std::cout << y->is_shared() << std::endl;
}

Выход:

false
true

Кроме того, вы можете использовать weak_from_this, чтобы получить доступ к методу weak_ptrexpired:

bool is_shared() const {
    return !weak_from_this().expired();
}

Спасибо @robinleander. Не могли бы вы мне сказать, где в стандарте C++ 11 написано «Вызов shared_from_this ... неопределенное поведение»?

mtyk1 02.05.2018 16:51

Другие связались с этим; см. раздел примечаний здесь: en.cppreference.com/w/cpp/memory/enable_shared_from_this/…

cisnjxqu 02.05.2018 16:52

«поведение не определено» и «поведение не определено» одинаковы? Хотелось бы узнать, как это написано в стандартных предложениях ISO C++.

mtyk1 02.05.2018 16:58

Я считаю, что это синонимы. В статье про UB упоминается фраза «Поведение не определено, если такая программа выполняется». Было бы очень неразумно употреблять эту фразу без пояснения, если бы была разница. en.cppreference.com/w/cpp/language/ub

cisnjxqu 02.05.2018 17:16

Другие вопросы по теме