MFC определяет функции для создания предопределенных исключений. Например, вы используете ::AfxThrowFileException()
для создания исключения типа CFileException
. Но что, если я определю свой собственный класс исключений, производный от CException
? Каков предпочтительный способ бросить его?
Есть ли проблемы, если я просто сделаю это:
if (!m_Settings.IsValid())
throw new CMyException(_T("This operation failed."));
В Visual Studio 2019 приведенный выше код генерирует следующее предупреждение Intellisense. Но я еще не видел примеров, вызывающих исключение с использованием make_unique
.
Warning C26409 Avoid calling new and delete explicitly, use std::make_unique instead (r.11).
Может ли кто-нибудь объяснить это или сослаться на какую-то текущую документацию?
@AndrewTruckle: Поскольку я не знаю, что такое набор правил, я бы сказал нет.
Перейдите в настройки вашего проекта, найдите раздел Анализ кода слева. Разверните узел Общий. На них находится настройка для набора правил. У вас установлено значение Собственные рекомендуемые правила Microsoft?
Он был установлен в Все правила Майкрософт. Я изменил его на Собственные рекомендуемые правила Microsoft. Это, кажется, удалило предупреждение - спасибо. Но я все еще не уверен, как лучше всего создать пользовательское исключение.
Просто бросьте их. Я использовал, например, throw new CChristianLifeMinistryEntryException(strError);
.
Ну, я пока. Я не уверен, что полностью понимаю причину таких функций, как AtlThrowFileException()
. Но я просто выброшу их, пока не найду вескую причину не делать этого.
Насколько я понимаю, это генерировать системное исключение, если оно соответствует вашим обстоятельствам. В противном случае бросайте свои. См.: docs.microsoft.com/en-us/cpp/mfc/…
Да, но опять же, когда вы создаете предоставленное исключение, рекомендуется использовать функцию ::AfxThrow...()
. Мой комментарий заключался в том, что я не был уверен, что полностью понял цель функции, а не просто выдал исключение.
Технически у вас есть два вопроса. Одно о предупреждении, которое вы получили, и одно о возбуждении исключений. Не могу прокомментировать последнее. Извиняюсь.
Обработка исключений — одна из тех областей, где видно, что MFC значительно старше C++. Поскольку исключения C++ были поздним дополнением к стандарту C++, MFC уже определилась со своей стратегией обработки исключений:
catch
, которое обрабатывает исключение, требуется для освобождения ресурсов, связанных с объектом исключения.Напротив, идиоматический способ обработки исключений C++ следует следующим рекомендациям:
const
) ссылке.С MFC вы можете использовать любой из вышеперечисленных. MFC предоставляет макросы исключений, которые помогают сделать первый менее подверженным ошибкам, хотя нет строгих требований к использованию какого-либо из них. Фактически, макросы исключений в версии 3.0 перешли к почти исключительно использованию обработки исключений C++ под капотом.
Правильный способ создания настраиваемых исключений в MFC зависит от кода, который его вызывает. Если этот код использует макросы исключений MFC, вам нужно будет указать указатель на динамически выделяемый объект исключения, например.
throw new CMyException(_T("This operation failed."));
или
THROW( (CException*) new CMyException(_T("This operation failed.")) );
и игнорировать предупреждение компилятора. Это необходимо, потому что макросы CATCH
всегда будут расширяться до предложений catch
, соответствующих типам указателей.
Если, с другой стороны, вызывающий код использует обработку исключений C++, нет проблем с выбросом ни по значению, ни по указателю, например.
throw CMyException(_T("This operation failed."));
// or
throw new CMyException(_T("This operation failed."));
и ловить по const
ссылке или указателю:
catch( CException const& ) {
// no cleanup required
}
// or
catch( CException* e ) {
// manual cleanup still required, unless the exception is re-thrown
e->Delete();
}
В предыдущем фрагменте также разрешено использовать оба предложения catch
, что позволяет вам подготовить свой вызывающий код для работы с сочетанием создания пользовательских исключений по значению в вашем коде, а также вызова предоставленного MFC кода, который вызывает динамически выделяемые объекты исключений. бросается указателем.
В некоторой степени даже разрешено смешивать обработку исключений C++ и макросы исключений MFC (Исключения: использование макросов MFC и исключений C++). Информация предоставлена только для полноты. Не рекомендуется смешивать исключения C++ и макросы исключений MFC, если только для этого нет веской причины, например. при постепенном переходе существующего кода с использования макроса исключений MFC на обработку исключений C++.
Вы использовали свой собственный «набор правил». У меня были такие предупреждения. Как только я вернулся к «Рекомендуемому набору правил», эти типы предупреждений прекратились.