为什么`throw MyClass'不起作用而且`throw MyClass()'呢?

时间:2012-09-27 11:48:49

标签: c++ exception

我在某处找到了(现在找不到来源)

MyClass *p1 = new MyClass;

MyClass *p2 = new MyClass();
只要MyClass提供默认构造函数,

基本上是等效的。编译器理解我想要做的事情并添加空括号。

如果是这种情况,为什么我不允许写

throw MyException;

但必须使用

throw MyException();

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

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

3 个答案:

答案 0 :(得分:3)

  

编译器理解我想要做的事情并添加空括号。

不,不;这两个表达式并不完全相同。区别在于如何初始化对象:第一个使用默认初始化,而第二个使用值初始化。因此它们对于定义默认构造函数的类是等效的;否则,第一个将保留未初始化的POD对象,而第二个将初始化为零。

  

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

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

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

  

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

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

答案 1 :(得分:1)

因为您没有抛出new异常,而是构建它。

请考虑以下事项:

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

new MyException; // works
new MyException();// works

答案 2 :(得分:0)

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

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

相同
MyException ex = MyException;

不会编译,但

MyException ex = MyException();

会。 FAQ示例简单地说明了相同的内容:

MyException ex();

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

MyException ex;

那样。

没有办法

throw MyException();

MyException ex = MyException();

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