8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

为什么不能用空括号调用默认构造函数?

Aayush Pandey 2月前

69 0

有什么充分的理由说明,在 C++ 中,一组空的圆括号(括号)对于调用默认构造函数无效?MyObject 对象;// ok - default ctorMyObject 对象(blah);/...

有什么充分的理由说明为什么空圆括号(括号)不能用于调用 C++ 中的默认构造函数?

MyObject  object;  // ok - default ctor
MyObject  object(blah); // ok

MyObject  object();  // error

我好像每次都会自动输入 \'()\'。有什么理由不允许这样做吗?

帖子版权声明 1、本帖标题:为什么不能用空括号调用默认构造函数?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Aayush Pandey在本站《object》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 有人应该想出一个更好的标题,但我想不出会是什么。至少要拼出“构造函数”来帮助搜索引擎。

  • 我注意到的一件事是,如果我只有默认构造函数,那么如果我使用,编译器不会给出任何错误

  • 最令人烦恼的解析

    这与所谓的“C++ 最令人头疼的解析”有关。基本上,任何可以被编译器解释为函数声明的东西都会被解释为函数声明。

    同一问题的另一个实例:

    std::ifstream ifs("file.txt");
    std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());
    

    v 被解释为具有 2 个参数的函数声明。

    解决方法是添加另一对括号:

    std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());
    

    或者,如果您有 C++11 和列表初始化(也称为统一初始化):

    std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};
    

    这样,它就不可能被解释为函数声明。

  • 挑剔:你可以在函数内部声明函数。在 C 中,这被称为局部函数,至少在 C++ 中也允许使用 extern \'C\' foo(); 风格。

  • @Casebash,std::vector 是返回类型;v 是函数名称;(打开正式参数列表;std::istream_iterator 是第一个参数的类型;ifs 是第一个参数的名称,ifs 周围的 () 会被有效忽略;第二个 std::istream_iterator 是第二个参数的类型,它是未命名的,它周围的 () 也会被忽略;');' 关闭参数列表和函数声明。

  • 涉及表达式语句和声明的语法存在歧义:以函数样式显式类型转换作为其最左边子表达式的表达式语句与第一个声明符以 ( 开头的声明难以区分。在这些情况下,语句就是声明。(C++ ISO/IEC(2003)6.8.1)

  • @Constantin,第二个参数后的括号不会被忽略。第二个参数不是 std::istream_iterator,而是指向不带参数并返回 istream_iterator 的函数的指针/引用。

  • 因为它被视为函数的声明:

    int MyFunction(); // clearly a function
    MyObject object(); // also a function declaration
    
  • 但它应该会出错,对吧?因为我们还没有定义 object() 函数,对吧?你能详细说明一下吗?我现在很困惑。提前谢谢您!

  • 顺便提一下,在我的主程序中,我甚至尝试了这些:any_variable_name random_function_name() 例如 int func1() 、double func2()、void func3() 等。它们全部都有效,也就是说我的程序编译时没有任何错误!但是,我没有定义任何这些函数,所以我应该会得到错误,对吗?

  • 引用 12

    @Milan 如果你真的尝试调用这些函数,我预计会出现链接器错误。否则它们只是声明

  • 函数声明使用相同的语法 - 例如函数 object ,不带参数并返回 MyObject

  • mm8 2月前 0 只看Ta
    引用 14

    我猜,编译器不知道这个语句:

    MyObject 对象();

    是一个构造函数调用或一个函数原型,声明一个名为 object 的 ,其返回类型为 MyObject 并且没有参数。

  • 您还可以使用更详细的构造方式:

    MyObject object1 = MyObject();
    MyObject object2 = MyObject(object1);
    

    在 C++0x 中,这也允许 auto

    auto object1 = MyObject();
    auto object2 = MyObject(object1);
    
  • @Casebash:编译器可能足够智能,使用一些类似 RVO 的优化来防止其效率低下。

  • @Stefan:您无需“猜测”;所有主流编译器都会出现复制省略,这种情况已经持续了十多年。这并不是说这是好的代码。

  • 正如多次提到的,这是一个声明。它是为了向后兼容。这是 C++ 中许多愚蠢/不一致/痛苦/虚假的领域之一,因为它的遗留问题。

  • 来自 n4296 [dcl.init]:

    [ 笔记:
    由于 () 初始化器 的语法不允许 , X a(); 声明 对象 ,但是不允许声明不带参数并返回 X 的 函数 。在某些其他初始化上下文中允许使用 () 形式(5.3.4、5.2.3、12.6.2)。
    —结束注释]

    C++11 链接
    C++14 链接

  • 正如其他人所说,这是一个函数声明。从 C++11 开始,如果您需要查看 明确告诉您使用了默认构造函数的 内容

    Jedi luke{}; //default constructor
    
返回
作者最近主题: