Создание пользовательского исключения в Visual C ++ 2019 - PullRequest
1 голос
/ 09 апреля 2019

MFC определяет функции для выдачи предопределенных исключений.Например, вы используете ::AfxThrowFileException(), чтобы вызвать исключение типа CFileException.Но что, если я определю свой собственный класс исключений, который происходит от CException?Какой предпочтительный способ его выбросить?

Есть ли проблемы, если я просто сделаю это:

if (!m_Settings.IsValid())
    throw new CMyException(_T("This operation failed."));

В Visual Studio 2019 приведенный выше код генерирует следующее предупреждение Intellisense.Но я пока не видел примеров, генерирующих исключение с использованием make_unique.

Предупреждение C26409 Не вызывайте new и не удаляйте явно, используйте вместо этого std :: make_unique (r.11).

Может кто-нибудь объяснить это или отослать меня к какой-то текущей документации?

1 Ответ

0 голосов
/ 16 апреля 2019

Обработка исключений - одна из тех областей, в которых показано, что 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 ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...