Вопросы об обработке исключений в C ++ - PullRequest
3 голосов
/ 19 октября 2010

1) Для удобства у меня вся программа в блоке try. Таким образом, я могу вызвать исключение в любой точке моего кода и знать, что оно будет обработано таким же образом. По мере того, как программа станет больше, эта техника приведет к снижению производительности?

2) Если объекты перераспределяются, когда они находятся вне области видимости, почему выбрасывание временного объекта будет допустимым? e.g.:

class Error : public std::exception  
{
  private:
    char *m;
  private:
    Error(char *l) : m(l) {}
    virtual char *what()
    {
      return m;
    }
};

int main()
{
  try
  {
    throw Error("test");
  }
  catch(std::exception &e)
  {
    puts(e.what());
    return -1;
  }
  return 0;
}

Почему в операторе throw временный объект не станет недействительным, поскольку он был объявлен только в области действия try?

3) В операционных системах Windows с языком, отличным от английского, будет ли what() член класса исключений STL возвращать строку char*? Или он может вернуть wchar_t* строку?

Ответы [ 2 ]

10 голосов
/ 19 октября 2010

Технически вы не бросаете реальный объект, вы бросаете его копию. Вот почему вы можете сойти с рук, бросив временный. Поймав ссылку, вы получите ссылку на копию.

Это может вас укусить, если вы выбросите исключение из блока catch, вы можете стать жертвой проблемы срезов. Вот почему вы не делаете:

catch (std::exception & e)
{
    throw e;  // bad, always throws std::exception rather than what was caught
}

а точнее

catch (std::exception & e)
{
    throw;  // good, rethrows the exact copy that you caught without making another copy
}

P.S. Нет правила, гласящего, что вы не можете вернуть строку UTF-8 из what. Это было бы до вас, чтобы преобразовать его в UTF-16 для ввода-вывода Windows. Стандартные классы исключений никогда не были специально разработаны или расширены для Unicode, а также не добавлены какие-либо нестандартные расширения только для Windows.

4 голосов
/ 19 октября 2010

1) Наличие всей программы в блоке try не повлечет за собой снижения производительности, за исключением того, что при включении исключений вообще

2) Это нормально, потому что вы бросаете по значению. Бросок по значению означает, что все, что вы бросаете, копируется при броске. Таким образом, выбрасывание любого временного кода вполне допустимо, потому что копия сделана.

3) Класс std :: exception, насколько я могу судить, может выдавать только char*. Однако вы всегда можете создать его подкласс и реализовать поддержку wchar, если хотите.

Стоит отметить, что вы не должны просто попытаться поймать около main(), если это то, что вы намеревались.

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