简体   繁体   English

C ++中的类对象创建

[英]Class object creation in C++

I have a basic C++ question which I really should know the answer to. 我有一个基本的C ++问题,我真的应该知道答案。

Say we have some class A with constructor A(int a) . 假设我们有一些带有构造函数A(int a)A What is the difference between: 有什么区别:

A test_obj(4);

and

A test_obj = A(4);

?

I generally use the latter syntax, but after looking up something unrelated in my trusty C++ primer I realized that they generally use the former. 我通常使用后一种语法,但在查找了我可靠的C ++入门中不相关的内容后,我意识到它们通常使用前者。 The difference between these two is often discussed in the context of built-in types (eg int a(6) vs int a = 6 ), and my understanding is that in this case they are equivalent. 这两者之间的差异经常在内置类型的上下文中讨论(例如int a(6) vs int a = 6 ),我的理解是在这种情况下它们是等价的。

However, in the case of user-defined classes, are the two approaches to defining an object equivalent? 但是,在用户定义的类的情况下,定义对象等效的两种方法是什么? Or is the latter option first default constructing test_obj , and then using the copy constructor of A to assign the return value of A(4) to test_obj ? 或者后一个选项是否首先默认构造test_obj ,然后使用A的复制构造函数将A(4)的返回值test_obj If it's this second possibility, I imagine there could be some performance differences between the two approaches for large classes. 如果这是第二种可能性,我想大型课程的两种方法之间可能存在一些性能差异。

I'm sure this question is answered somewhere on the internet, even here, but I couldn't search for it effectively without finding questions asking the difference between the first option and using new , which is unrelated. 我确信这个问题在互联网上的某个地方得到了解答,即使在这里也是如此,但是如果没有找到问题,要求区分第一个选项和使用new ,这是无关的,我无法有效地搜索它。

A test_obj = A(4); conceptually does indeed construct a temporary A object, then copy/move-construct test_obj from the temporary, and then destruct the temporary. 在概念上确实构造了一个临时的A对象,然后从临时复制/移动构造test_obj ,然后破坏临时。

However this process is a candidate for copy elision which means the compiler is allowed to treat it as A test_obj(4); 但是,此过程是复制省略的候选者,这意味着允许编译器将其视为A test_obj(4); after verifying that the copy/move-constructor exists and is accessible. 在验证复制/移动构造函数存在且可访问之后。

From C++17 it will be mandatory for compilers to do this; 从C ++ 17开始,编译器必须这样做; prior to that it was optional but typically compilers did do it. 在此之前它是可选的,但通常编译器确实这样做。

Performance-wise these are equivalent, even if you have a non-standard copy constructor, as mandated by copy elision . 在性能方面,这些是等效的,即使你有一个非标准的复制构造函数,正如copy elision所强制要求的那样。 This is guaranteed since C++17 but permitted and widely present even in compilers conforming to earlier standards. 这是自C ++ 17以来的保证,但即使在符合早期标准的编译器中也允许并广泛存在。

Try for yourself, with all optimizations turned off and the standard forced into C++11 (or C++03, change the command line in the top right): https://godbolt.org/g/GAq7fi 尝试自己,关闭所有优化并将标准强制转换为C ++ 11(或C ++ 03,更改右上角的命令行): https//godbolt.org/g/GAq7fi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM