Я пытаюсь создать функцию-член, которая возвращает, сохранено ли оно в 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/…: "Разрешено вызывать shared_from_this только для ранее совместно используемого объекта, то есть для объекта, управляемого std :: shared_ptr. В противном случае поведение не определено (до C++ 17) std :: bad_weak_ptr выбрасывается (конструктором shared_ptr из по умолчанию weak_this) (начиная с C++ 17) ". Это зависит от того, какую версию C++ вы используете.
Я не уверен, что shared_from_this
вообще может вернуть nullptr
в четко определенной программе.
@ FrançoisAndrieux Спасибо. Я читал руководство на основе C++ 11, но в нем ничего не говорится об этом случае.
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_ptr
expired
:
bool is_shared() const {
return !weak_from_this().expired();
}
Спасибо @robinleander. Не могли бы вы мне сказать, где в стандарте C++ 11 написано «Вызов shared_from_this ... неопределенное поведение»?
Другие связались с этим; см. раздел примечаний здесь: en.cppreference.com/w/cpp/memory/enable_shared_from_this/…
«поведение не определено» и «поведение не определено» одинаковы? Хотелось бы узнать, как это написано в стандартных предложениях ISO C++.
Я считаю, что это синонимы. В статье про UB упоминается фраза «Поведение не определено, если такая программа выполняется». Было бы очень неразумно употреблять эту фразу без пояснения, если бы была разница. en.cppreference.com/w/cpp/language/ub