Итак, допустим, у меня есть:
struct test {
bool a;
int b;
};
int main()
{
std::unique_ptr<test> ptr;
// don't init the ptr
try
{
if (!ptr->a)
{
std::cout << "ok" << std::endl;
}
}
catch (const std::exception &ex)
{
std::cout << "ex: " << ex.what() << std::endl;
}
return 1;
}
Итак, здесь я устанавливаю уникальный указатель, но я не инициализирую его (чтобы имитировать это в более крупной базе кода), но я хочу поймать исключение.
Проблема в том, что мое исключение не вызывается - просто вылетает (ошибка доступа к памяти)
Я прочитал несколько похожих вопросов (но не совсем одинаковых), в которых предлагалось передать исключение по ссылке, но это не сработало.
Так можно ли перехватить исключение отмены ссылки unique_ptr?
Обновлено: Я должен добавить, что это находится в окне Windows 7 с исполняемым файлом MSVS2012 - на случай, если это актуально!
@RichardCritten о ... есть ли способ сделать то, что я пытаюсь сделать? - У меня есть список unique_ptr - я пытался избежать индивидуальной проверки каждого из них, помещая вокруг него блок try ... но если он не генерирует исключение, тогда, я думаю, мне нужно выполнить if (ptr) {...} для каждого из них?
Почему у вас есть умные указатели (std::unique_ptr), которым ничего не принадлежит? Это похоже на XY-проблему.
@RichardCritten Я использую умные указатели, чтобы мне не приходилось так сильно беспокоиться о сборке мусора и так далее ... В моем коде, когда я создаю новый указатель, конструктор (указанного типа) может выйти из строя, и если да умный указатель фактически равен nullptr. Итак, я хочу проверить это условие ....
Выбрасывать исключение, когда конструируемый объект терпит неудачу, и не создавать std :: unique_ptr`.
@RichardCritten хорошо, поэтому я вызываю стороннюю функцию, которая возвращает либо указатель, либо nullptr. Я мог бы использовать необработанные указатели, но я хотел использовать unique_ptr для автоматической сборки мусора ... Я считаю, что это один из вариантов использования unique_ptr? Итак, исключение, которое я хочу вызвать, - это когда я получаю возвращенный nullptr ... В любом случае, я думаю, что вопрос получен (т.е. не могу делать то, что пытаюсь), я переместу проверку исключения, чтобы проверить каждый указатель. Не стесняйтесь добавлять свой первый комментарий в качестве ответа, я размечу его.
Вы можете создать свой собственный умный указатель, который будет проверять / бросать каждый раз, когда вы его используете. Но это неизбежно несколько снижает производительность. Между прочим, C++ выдаст исключение (по умолчанию), если не сможет выделить ваш объект при его создании.
Или заверните функцию стороннего создателя в чек.





So is it possible to catch a unique_ptr de-reference exception?
Не существует исключения разыменования unique_ptr, которое можно было бы перехватить.
Как сообщает документация говорит,
The behavior is undefined if
get() == nullptr
Вы можете легко написать свой собственный умный указатель с этим Java-подобным поведением, но это означает оплату теста и ветвления при разыменовании каждый, что в целом кажется глупым.
Для немного другой проблемы, описанной в комментариях:
I have a list of unique_ptr's - I was trying to avoid individually checking each one by putting a try block around it.
разумное решение, вероятно, состоит в том, чтобы проверять его один раз, а не при каждом последующем разыменовании:
if (any_of(begin(ptrs), end(ptrs), logical_not<unique_ptr<test>>{})
{
throw MyNullPointerException();
}
В последующих комментариях вы можете просто добавить обертку проверки и выброса к своей функции построения.
В C++ 17 вы можете почти получить то, что хотите, вместо этого вернув optional<unique_ptr<test>> (то есть он либо содержит заполненный unique_ptr, либо вообще ничего: в этом случае вызов value для извлечения unique_ptr приведет к выдаче std::bad_optional_access, если его нет. действительно один там).
Если вы можете импортировать ot (или у вас нет C++ 17), GSL, вероятно, будет даже лучше с gsl::not_null<T>. Например, вы можете вместо этого хранить эти вещи в своем контейнере.
using unique_not_null = std::unique_ptr<gsl::not_null<test>>;
gsl::not_null?
Отмена ссылки на неинициализированный указатель является неопределенным поведением и не вызывает исключения.