1

我在某处读到(现在找不到源)

MyClass *p1 = new MyClass;

MyClass *p2 = new MyClass();

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

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

throw MyException;

但必须使用

throw MyException();

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

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

4

3 回答 3

3

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

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

为什么我不允许写作throw MyException;

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

MyException不是表达式;它只是一个类型名称。你只能抛出一个表达式的值,所以throw MyException;是无效的。无法创建默认初始化的临时对象。

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

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

于 2012-09-27T12:01:51.127 回答
1

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

考虑以下:

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

new MyException; // works
new MyException();// works
于 2012-09-27T11:51:11.623 回答
0

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

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

MyException ex = MyException;

不会编译,但是

MyException ex = MyException();

将。常见问题解答示例仅说明了以下内容:

MyException ex();

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

MyException ex;

将。

没办法

throw MyException();

或者

MyException ex = MyException();

可以解释为函数声明,因此它们可以工作。

于 2012-09-27T11:50:47.070 回答