Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么';对象obj=Object()和对象obj()之间的区别是什么?_C++ - Fatal编程技术网

C++ 什么';对象obj=Object()和对象obj()之间的区别是什么?

C++ 什么';对象obj=Object()和对象obj()之间的区别是什么?,c++,C++,我认为它有很多关于它的信息,但我不知道这是怎么叫的。我无法理解接下来两个代码字符串之间的区别: Object obj(); 及 你能解释一下吗?或者至少说怎么称呼它 Object obj(); 声明一个函数名obj,该函数返回一个对象,不接受任何参数。这通常不是你想要的 Object obj = Object(); 声明名为obj的对象,然后使用临时默认构造的对象进行复制初始化。除非将对象重置回默认状态,否则通常也不希望执行此操作 通常,如果您想在不调用构造函数的情况下构造,可以使用 Ob

我认为它有很多关于它的信息,但我不知道这是怎么叫的。我无法理解接下来两个代码字符串之间的区别:

Object obj();

你能解释一下吗?或者至少说怎么称呼它

Object obj();
声明一个函数名
obj
,该函数返回一个
对象
,不接受任何参数。这通常不是你想要的

Object obj = Object();
声明名为
obj
对象
,然后使用临时默认构造的
对象
进行复制初始化。除非将对象重置回默认状态,否则通常也不希望执行此操作

通常,如果您想在不调用构造函数的情况下构造,可以使用

Object obj;
//or
Object obj{};
差别很大

第一个是一个函数原型,它是一个不带参数并返回对象的函数

第二个通过调用默认构造函数实例化对象。为避免疑问,不调用赋值运算符

在第一种情况下去掉括号,使语句等效

Object obj();
声明一个函数,而不是一个对象!这是“最麻烦的解析”的一个实例

要求
对象
具有可访问的移动构造函数或复制构造函数(尽管编译器最终可能会省略移动/复制)

创建对象的简单方法包括:

Object obj;
Object obj{};
不是对象的实例化,它是函数
obj
的声明,该函数不带任何参数,并返回
object
的实例

Object obj;
是一个
默认初始化
,即使用隐式构造函数实例化(因此,默认隐式构造函数或用户定义的不带参数的非
显式
构造函数),此声明调用非POD
对象
成员的隐式构造函数,对于POD类型,它不会初始化它们(它们不会被归零)。这适用于
对象
等的成员

Object obj{};
是列表初始化或聚合初始化(如果
对象
是聚合)。它以不同方式调用的对象,对于空大括号,行为是相同的:POD类型的所有成员都是零初始化的,非POD类型的成员都是默认初始化的

Object obj = Object();
从理论上讲,有两个步骤:1)创建临时
对象
实例;2) 然后通过复制构造函数/移动构造函数/复制运算符/移动运算符构造obj。但在实践中,它是默认构造的,考虑到复制/移动省略(默认情况下,在所有现代编译器上都会启用它,即使所有优化都已关闭,您也必须显式禁用省略)。最好不要使用这种变体

结论前

选择

Object obj;

如果希望快速初始化而不将其POD成员归零,请选择“第一”。 如果要确保在实例化
对象
后其所有POD成员都为零,请选择second

Object obj;
实际上,在首次读取其成员之前,这两种变体在所有现代操作系统上的运行速度都是相同的

所以

结论

使用值初始化:

Object obj{};

除非你需要在异域系统上实现实时性能。

好吧,为什么我在使用
Object obj()
时会遇到问题,但在使用
Object obj=Object()时却没有问题?@ghostman你应该使用
Object obj,不带parentheses@juanchopanza现在我注意到括号你是对的,它们是不同的。我想OP说的是对象obj
,不是对象obj()
。谢谢!我明白了,但我不知道
对象对象对象{}是不同的。谢谢你的高级答案<代码>对象对象对象{}是值初始化,而不是默认初始化。在某些情况下,这可能会有所不同。删除括号并不能使语句等效<代码>对象obj=Object()创建对象的临时实例,然后从临时复制构造obj。在大多数情况下,会有拷贝省略,但在少数情况下,这是有意义的。第二个拷贝/移动从一个临时文件构造
obj
。这是不同的,因为如果对象不可移动,它将不会编译。此外,如果它是可移动的,它可能具有与
Object obj不同的行为虽然实际编写具有不同行为的代码会被认为是不好的风格。谢谢您的解释!应该注意,
objectobj{}
是C++11的一项功能,在早期版本中不可用。我不得不定期处理这个问题,因为我们的一些源代码被另一个团队共享,由于技术原因,该团队仍在使用C++09,所以两个项目的任何通用文件都不能使用这个符号。@DarrelHoffman,拜托,今天是2015年的结束!C++14是一个标准,C++17即将推出。这并不能改变许多公司仍在使用旧标准的事实。OP使用C++标签而不是C++ 11(或以后)的标签,所以不能假定它们使用最新的标准。@ VLADON:在转换成本方面有很多开销,许多公司仍然被迫用各种原因来处理遗留代码。当然,如果由我决定的话,我会使用最新和最棒的东西,但我们并不总是有这样的选择,尤其是在已经存在了十多年的大公司。我不止一次因为使用C++11风格的代码而陷入麻烦,这些代码在我的项目中有效,但不会为其他团队编译,这些团队正在使用与旧编译器相同的文件。我只是想指出,不是每个人都有这样的选择。
Object obj;
Object obj{};
Object obj{};