我对用于实例化对象的不同语法感到困惑。
这是我的课程:
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;
}
我对标有default
或copy
的人没有问题。我只想知道,使用???
调用哪个构造函数,因为不调用默认构造函数。可以看出,它与()
初始化有关。
我知道这可能并不重要,但我对此表示怀疑。
任何人都可以帮忙!
答案 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
。然后,声明两个函数f
和h
,它们具有一个未命名的参数并返回一个Object
。参数的类型为:没有参数并返回Object
的函数。
这被称为most vexing parse。基本上,C ++标准说:“如果可以将其解析为函数声明,则必须将其解析为函数声明。”叮当声甚至警告:-Wvexing-parse
。