C++ 对象实例化 - 当使用空括号实例化对象时调用哪个构造函数
C++ Object Instantiation - Which constructor is called when an object is instantiated using empty parenthesis
我对用于实例化对象的不同语法感到困惑。
这是我的 class:
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
的没有问题。我只想知道,哪个构造函数被调用为 ???
的构造函数,因为没有调用默认构造函数。跟()
初始化有关系吗,可以看出
我知道这可能不重要,但我对此持怀疑态度。
谁能帮忙!
这三个声明都是函数声明,而不是变量定义(如您所料)。
Object b();
声明了一个名为 b
的函数,它不带任何参数 returns Object
.
Object f ( Object() );
声明了一个名为 f
的函数,它接受一个未命名的参数,该参数的类型是一个函数返回 Object
并且不带任何参数(即 Object()
),并且 returns Object
。 Object h ( Object() );
.
同样
作为解决方法,Object b();
您可以
Object b;
Object b{}; // since C++11
对于 Object f ( Object() );
你可以
Object f ( ( Object() ) );
Object f ( Object{} ); // since C++11
Object f { Object{} }; // since C++11
Object f { Object() }; // since C++11
有关更多信息,请参阅 most vexing parse。
它实际上没有调用任何构造函数。
当您更改对象 class 以便所有字段都是 public(以便您可以查看它们)时:
#include <iostream>
class Object
{
public:
int field = 0;
Object() = default;
~Object() = default;
Object( const Object& obj ) = default;
};
然后你尝试调用main方法中的空括号:
int main()
{
Object b();
std::cout << b.field << '\n';
return 0;
}
你得到一个错误,因为 b
不是一个对象而是一个函数:
错误:请求'b'中的成员'field',它是非class类型'Object()'
这就是为什么当你想调用空括号构造函数时,你必须在没有任何括号的情况下调用它:
int main()
{
Object b; // this is correct
std::cout << b.field << '\n';
return 0;
}
您正确识别了所有构造函数。你不确定的三个不要按照你的想法去做
Object b();
Object f ( Object() );
Object h ( Object() );
所有这些都是函数声明,而不是变量定义。
您声明了一个函数 b
,它没有参数并且 return 是一个 Object
。然后声明两个函数,f
和 h
,它们有一个未命名的参数和 return 和 Object
。参数类型为:无参函数,returning Object
.
这就是所谓的most vexing parse。基本上 C++ 标准说:“如果它可以被解析为函数声明,则它必须被解析为函数声明。” Clang 甚至有一个警告:-Wvexing-parse
.
我对用于实例化对象的不同语法感到困惑。
这是我的 class:
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
的没有问题。我只想知道,哪个构造函数被调用为 ???
的构造函数,因为没有调用默认构造函数。跟()
初始化有关系吗,可以看出
我知道这可能不重要,但我对此持怀疑态度。
谁能帮忙!
这三个声明都是函数声明,而不是变量定义(如您所料)。
Object b();
声明了一个名为 b
的函数,它不带任何参数 returns Object
.
Object f ( Object() );
声明了一个名为 f
的函数,它接受一个未命名的参数,该参数的类型是一个函数返回 Object
并且不带任何参数(即 Object()
),并且 returns Object
。 Object h ( Object() );
.
作为解决方法,Object b();
您可以
Object b;
Object b{}; // since C++11
对于 Object f ( Object() );
你可以
Object f ( ( Object() ) );
Object f ( Object{} ); // since C++11
Object f { Object{} }; // since C++11
Object f { Object() }; // since C++11
有关更多信息,请参阅 most vexing parse。
它实际上没有调用任何构造函数。
当您更改对象 class 以便所有字段都是 public(以便您可以查看它们)时:
#include <iostream>
class Object
{
public:
int field = 0;
Object() = default;
~Object() = default;
Object( const Object& obj ) = default;
};
然后你尝试调用main方法中的空括号:
int main()
{
Object b();
std::cout << b.field << '\n';
return 0;
}
你得到一个错误,因为 b
不是一个对象而是一个函数:
错误:请求'b'中的成员'field',它是非class类型'Object()'
这就是为什么当你想调用空括号构造函数时,你必须在没有任何括号的情况下调用它:
int main()
{
Object b; // this is correct
std::cout << b.field << '\n';
return 0;
}
您正确识别了所有构造函数。你不确定的三个不要按照你的想法去做
Object b();
Object f ( Object() );
Object h ( Object() );
所有这些都是函数声明,而不是变量定义。
您声明了一个函数 b
,它没有参数并且 return 是一个 Object
。然后声明两个函数,f
和 h
,它们有一个未命名的参数和 return 和 Object
。参数类型为:无参函数,returning Object
.
这就是所谓的most vexing parse。基本上 C++ 标准说:“如果它可以被解析为函数声明,则它必须被解析为函数声明。” Clang 甚至有一个警告:-Wvexing-parse
.