Обнаружение, если объект принадлежит умному указателю - PullRequest
1 голос
/ 05 января 2012

У меня есть класс, который наследуется от enable_shared_from_this, и метод, который возвращает общий указатель, вызывая shared_from_this ().Я хотел бы в этом методе определить, принадлежит ли объект shared_ptr и если не бросить.Я пробовал что-то вроде этого:

shared_ptr<T> getPointer() {
    shared_ptr<T> ptr(shared_from_this()));
    if(!ptr)
        throw "Not owned by smart pointer"
    return ptr;
}

Это не работает, хотя, потому что при создании ptr выдается исключение плохого слабого указателя.Есть ли другой способ.

Ответы [ 2 ]

3 голосов
/ 05 января 2012

Одним из предварительных условий вызова shared_from_this() для объекта t является «должен существовать хотя бы один shared_ptr экземпляр p, которому принадлежит t» (см. документация Boost ). Спецификация C ++ 11 enable_shared_from_this имеет такое же требование.

Поскольку нет других (задокументированных) членов enable_shared_from_this, похоже, нет способа проверить, действительно ли объект, полученный из enable_shared_from_this, принадлежит shared_ptr.

При этом, для ясности, вероятно, было бы лучше всего извлечь из enable_shared_from_this, только если объекты этого типа всегда будут принадлежать shared_ptr. Таким образом, нет путаницы.

3 голосов
/ 05 января 2012

Глядя на интерфейс в стандарте, я не вижу ничего, что могло бы сделать достойный тест.Конечно, вы всегда можете обойти проблему:

std::shared_ptr<T> getPointer() {
    try {
        return this->shared_from_this());
    }
    catch (std::bad_weak_ptr const&) {
        throw std::runtime_error("not owned by smart pointer");
    }
}

Конечно, вы также можете просто не перехватить исключение std::bad_weak_ptr и сделать так, чтобы исходное исключение выходило из функции.

Кстати, при выдаче исключений настоятельно рекомендуется выбрасывать исключение, полученное из std::exception.Если вы когда-нибудь получили исключение, вы ничего не знаете, вы проклянете парня, который его создал, потому что не всегда легко получить это исключение, чтобы выяснить, о чем оно (хотя отладчики могут помочь, если необходимо, установив перерывуказать на внутреннюю функцию, генерирующую исключение).Гораздо проще просто написать результат what().

...