【问题标题】:Why `throw MyClass' doesn't work and `throw MyClass()' does?为什么 `throw MyClass' 不起作用而 `throw MyClass()' 起作用?
【发布时间】:2012-09-27 11:48:48
【问题描述】:

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

MyClass *p1 = new MyClass;

MyClass *p2 = new MyClass();

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

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

throw MyException;

但必须使用

throw MyException();

? (是的,行首的问号。)

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

【问题讨论】:

  • C++ 中一个有趣的怪癖:不能有值初始化的自动对象,也不能有默认初始化的临时对象。

标签: c++ exception


【解决方案1】:

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

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

为什么我不能写throw MyException;

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

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

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

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

【讨论】:

  • 为了确保我理解正确:“第一个使用默认初始化,第二个使用值初始化。” 这意味着第一个调用默认构造函数,而第二个创建一个临时对象并使用赋值运算符?
  • @peter.slizik:不。如果类有一个非平凡的默认构造函数,那么两者都会使用它。如果不是,则默认初始化将使 POD 对象未初始化,而值初始化会将它们初始化为零值。两者都不会创建临时或使用分配。
  • @peter.slizik:有关 C++ 中各种初​​始化类型的更多详细信息,请参阅 this question
  • 感谢您的链接,我从未听说过这种区别。原因可能就在这里:要意识到“值初始化”是 C++ 2003 标准中的新内容 - 它在 1998 年的原始标准中不存在。
【解决方案2】:

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

考虑以下:

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

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

【讨论】:

    【解决方案3】:

    FAQ 中列出的情况不同,此处不适用。

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

    MyException ex = MyException;
    

    不会编译,但是

    MyException ex = MyException();
    

    会的。 FAQ 示例简单地说明了以下内容:

    MyException ex();
    

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

    MyException ex;
    

    会的。

    没有办法

    throw MyException();
    

    MyException ex = MyException();
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-30
      • 1970-01-01
      相关资源
      最近更新 更多