为什么"throw MyClass"不起作用,而"throw MyClass()"却行得通?

Why `throw MyClass' doesn't work and `throw MyClass()' does?

本文关键字:throw MyClass 行得通 不起作用 为什么      更新时间:2023-10-16

我在某处读到

MyClass *p1 = new MyClass;

MyClass *p2 = new MyClass();

本质上是等效的,前提是MyClass提供了默认构造函数。编译器理解我想要做什么,并添加空括号。

如果是这样的话,为什么我不被允许写

throw MyException;

但必须使用

throw MyException();

(是的,一行开头有一个问号。)

为了增加更多的混乱,C++FAQ建议第二个用例(new MyClass())不调用构造函数,而是调用用operator()定义的函数。

编译器了解我想要做什么,并添加空括号。

没有;这两种表达方式不完全等同。不同之处在于对象的初始化方式:第一种使用默认初始化,而第二种使用值初始化。因此,它们对于定义默认构造函数的类是等价的;否则,第一个将不初始化POD对象,而第二个将初始化它们为零。

为什么不允许我写throw MyException;

MyException()是一个创建值初始化的临时对象的表达式;你可以抛出它,就像抛出任何其他合适表达式的值一样。

MyException不是一个表达式;它只是一个类型名称。您只能抛出表达式的值,因此throw MyException;无效。没有办法创建一个默认的初始化临时。

为了增加一些混乱,C++常见问题解答建议第二个用例(new MyClass())不调用构造函数,而是调用用运算符()定义的函数。

没有。它说,像List x();这样的声明声明了一个返回类型为List的函数,而不是(正如人们可能认为的)List类型的值初始化对象。它与新表达式或operator()无关。

因为您不是抛出new异常,而是构造它。

考虑以下内容:

MyException exception = MyException(); // works
MyException exception = MyException; // doesn't work
new MyException; // works
new MyException();// works

常见问题解答中列出的情况不同,此处不适用。

MyException在第一种情况下只是一个类型名称,在第二种情况下创建一个变量。这只是语法。与相同

MyException ex = MyException;

不会编译,但

MyException ex = MyException();

会的。FAQ示例简单地说明了以下等价物:

MyException ex();

这确实是一个函数声明,而:

MyException ex;

会的。

不可能

throw MyException();

MyException ex = MyException();

可以被解释为函数声明,所以它们可以工作。