C++异常抛出空类

C++ Exceptions Throw Empty Class

本文关键字:异常 C++      更新时间:2023-10-16

以下摘录自"编程:使用C++的原理和实践"。我被throw 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";
}

Bad_area()是对类Bad_area的默认构造函数的显式调用
也就是说,throw Bad_area()所做的是直接返回(抛出)类Bad_area的一个匿名实例。

与Java或C#等OO语言中直接返回实例的情况相同。例如:

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

请注意,在C++中很少使用对构造函数的显式调用,因为实例的生存期是基于RAII的
只有少数情况下显式调用是个好主意,其中大多数都像您的示例,返回语句。例如,一个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 };
    } 
};

另一方面,execpt指出,在特殊情况下,必须避免直接调用构造函数。使用Java风格的新C++代码是很常见的。例如:

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++书有效的C++被认为是未来Java类程序员的功劳。