C ++ - Разница между "throw new BadConversion (" xxx ")" и "throw BadConversion (" xxx ")" - PullRequest
9 голосов
/ 20 декабря 2010
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html
class BadConversion : public std::runtime_error {
 public:
   BadConversion(std::string const& s)
     : std::runtime_error(s)
     { }
 };

 inline std::string stringify(double x)
 {
   std::ostringstream o;
   if (!(o << x))
     throw BadConversion("stringify(double)");
     // throw new BadConversion("stringify(double)");
   return o.str();
 } 

[Q1] Когда мы генерируем исключение в функции, в чем разница между throw new ClassName () и throw ClassName ()?

[Q2] Какой вариант лучше?

Спасибо

Ответы [ 4 ]

9 голосов
/ 20 декабря 2010

[A1] С throw new вам нужно catch указатель. В этом случае язык не указывает, кто отвечает за освобождение, поэтому вам придется установить свое собственное соглашение (как правило, вы возлагаете ответственность за отлов). Без new вы захотите catch по ссылке.

[A2] Если вы находитесь в рамках, которая обычно бросает указатели, вы можете последовать их примеру. Остальное, throw без new. См. Также C ++ FAQ, пункт 17.14 .

1 голос
/ 20 декабря 2010

В вашей базе кода вы должны выбрать один метод и придерживаться его для согласованности.

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

Я лично предпочитаю бросать объекты, а не указатели (основная причина, по которой я выбираю это, а не указатели, состоит в том, что они имитируют стандартную библиотеку). Хотя вполне возможно бросить указатели, вопрос о собственности поднимает свою уродливую голову. Кто (если кто-нибудь) отвечает за удаление указателя?

1 голос
/ 20 декабря 2010

throw new BadConversion(”xxx“) создает новый объект в куче и создает указатель на него.Этот объект должен быть удален блоком catch.Я не могу придумать вескую причину, почему вы хотели бы сделать это.

Другая версия позаботилась о RAII, используйте это.

1 голос
/ 20 декабря 2010

throw new ClassName() бросает указатель на ClassName.Вам нужно catch (ClassName * pc).Это не очень хорошая идея.Если new возвращает ноль или выбрасывает, то у вас есть нулевой указатель, когда вы ловите, или у вас двойное исключение.

throw ClassName() - это обычный способ вызвать исключение.Вам нужно catch (const ClassName & pc).

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