Исключения в C ++: пустой класс

Ниже приведен отрывок из раздела «Программирование: принципы и практика использования C ++». Я смущен бросить Bad_area () нотации. Книга пытается объяснить это: «Bad_area () означает« Создать объект типа Bad_area »», продолжая с того, что затем выбрасывает этот тип. Это объяснение не соответствует нотации присваивания, например. int x = 1 == int x (1); или же Bad_area x;.

Пример кода (закомментирован try-блок):

class Bad_area {}; // a type specifically for reporting errors from area()

// calculate area of a rectangle
// throw a Bad_area exception in case of a bad argument
int area(int length, int width)
{
if (length<=0 || width<=0) throw Bad_area();
return length*width;
}

int main()
try {
// ...
}
catch (Bad_area) {
cout << "Oop! bad arguments to area()\n";
}

0

Решение

Bad_area() явный вызов конструктора по умолчанию класса Bad_area,
Что это throw Bad_area() делает, чтобы возвратить (бросить) непосредственно экземпляр класса anonimus Bad_area,

То же, что и в языках OO, таких как Java или C #, когда вы возвращаете экземпляр напрямую. Например:

void foo() throws MyException
{
if( error ) throw new MyException();
}

Обратите внимание, что явные вызовы конструкторов редко используются в C ++, потому что время жизни экземпляров основано на RAII.
Есть только несколько случаев, когда явный вызов является хорошей идеей, большинство из них, как ваш пример, операторы return. Например, point_2d класс, в который легко вписываются алгебраические методы:

struct point_2d
{
float x;
float y;

point_2d(float _x = 0.0f , float _y = 0.0f) : x( _x ) , y( _y ) {}

//Easy inlineable addition:
point_2d operator+(const point_2d& lhs , const point_2d& rhs)
{
return point_2d{ lhs.x + rhs.x , lhs.y + rhs.y };
}
};

С другой стороны, за исключением исключительных случаев, следует избегать прямых обращений к конструкторам. Привычно видеть новый код C ++ в стиле Java. Например:

int main()
{
point_2d* point = new point_2d( 10.0f , 10.0f ); //Ok, this is not exactly a call to
//to the ctor, but has the same meaning.
//WTF why you use dynamic memory here?
}

Или правильное объявление переменной C ++ с последующей инициализацией Java:

int main()
{
point_2d point;

point = point_2d( 10.0f , 10.0f ); //WTF!!!
}

В зависимости от компилятора или если оптимизации отключены (все знают, что noobs никогда не включают оптимизации …), это приводит к:

  • Вызов конструктору point_2d (явный вызов)
  • Вызов point_2d::operator=
  • Вызов деструктору point_2d (уничтожение временного, созданного вызовом ctor).

Или, наконец, то же самое, но все в одной строке:

int main()
{
point_2d point = point_2d( 10.0f , 10.0f ); //WTF!!!
}

Это вызов конструктора point_2d, за которым следует вызов конструктора копирования point_2d для инициализации переменной с созданным временным.

Обратите внимание, что производительность в этом случае не имеет значения, потому что это не стиль C ++ / способ делать вещи. Каждый, кто пишет код C ++ таким образом, должен пойти на покупку хорошая книга по С ++. Эффективный C ++ был отредактирован с учетом будущих Java-подобных программистов.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector