C ++对象实例化-使用空括号实例化对象时调用哪个构造函数

时间:2020-05-09 09:25:30

标签: c++ initialization instantiation

我对用于实例化对象的不同语法感到困惑。

这是我的课程:

class Object
{

private:

    int field = 0;

public:

    Object() = default; // Just for testing.
    ~Object() = default; // Just for testing.

    Object( const Object& obj ) = default; // Just for testing.

};

这是主要方法:

int main()
{
    Object b(); // ???
    Object c{}; // default
    Object d = Object(); // default
    Object e = Object{}; // default
    Object f ( Object() ); // ???
    Object g { Object() }; // default
    Object a; // default but avoid
    Object h ( Object() ); // ???
    Object i { Object{} }; // default
    Object j = i; // copy
    Object k( j ); // copy
    Object l{ k }; // copy
    Object m = { l }; // copy
    Object n = ( m ); // copy
    auto o = Object(); // default
    auto p = Object{}; // default
    return 0;
}

我对标有defaultcopy的人没有问题。我只想知道,使用???调用哪个构造函数,因为不调用默认构造函数。可以看出,它与()初始化有关。

我知道这可能并不重要,但我对此表示怀疑。

任何人都可以帮忙!

3 个答案:

答案 0 :(得分:2)

这三个声明都是函数声明,而不是变量定义(如您所料)。

Object b();声明了一个名为b的函数,该函数不执行任何操作并返回Object

Object f ( Object() );声明了一个名为f的函数,该函数采用一个未命名的参数,该参数的类型为返回Object但不接收任何值的函数(即Object()),然后返回{{ 1}}。对于Object同样。

作为解决方法,对于Object h ( Object() );,您可以

Object b();

对于Object b; Object b{}; // since C++11 ,您可以

Object f ( Object() );

有关更多信息,请参见most vexing parse

答案 1 :(得分:2)

实际上并没有调用任何构造函数。

当您更改Object类以便所有字段都是公共的(以便您可以查看它们)时:

#include <iostream>
class Object
{
public:
    int field = 0;
    Object() = default;
    ~Object() = default;
    Object( const Object& obj ) = default;
};

然后尝试在主方法中调用空括号:

int main()
{
    Object b();
    std::cout << b.field << '\n';
    return 0;
}

由于b不是对象而是函数,您会收到错误消息:

错误:请求'b'中的成员'field',该成员属于非类类型'Object()'

这就是为什么当您要调用空括号构造函数时,必须在不带任何括号的情况下调用它:

int main()
{
    Object b;    // this is correct
    std::cout << b.field << '\n';
    return 0;
}

答案 2 :(得分:1)

您正确识别了所有构造函数。您不确定的三个都不按照您的想法做。

Object b();
Object f ( Object() );
Object h ( Object() );

所有这些都是函数声明,而不是变量定义。

您声明一个没有参数的函数b,并返回一个Object。然后,声明两个函数fh,它们具有一个未命名的参数并返回一个Object。参数的类型为:没有参数并返回Object的函数。

这被称为most vexing parse。基本上,C ++标准说:“如果可以将其解析为函数声明,则必须将其解析为函数声明。”叮当声甚至警告:-Wvexing-parse