可能重复:< br >什么是复制省略和返回值优化?
我很难理解为什么在下面的代码中没有调用复制构造函数。
#include <iostream>
class Test
{
public:
Test(int){std::cout << "Test()" << std::endl;}
Test(const Test&){std::cout << "Test(const Test&)" << std::endl;}
};
int main()
{
// Test test;
Test test2(Test(3));
return 0;
}
有人能解释一下为什么只调用构造函数,不调用复制构造函数吗?< br >谢谢。
正如其他人已经很好地提到的那样,这是因为编译器的优化。
我还没有检查过它,但你可能会编译你的代码优化,再次没有,看看汇编器代码。那么你也应该肯定地看到一些差异。
这是因为编译器执行了优化。允许编译器执行此类优化,尽管这不是一项要求,因此不能保证。
请注意一个重要的一点,即使最终不调用复制构造函数,它在语义上也需要可访问。也就是说,如果您将复制构造函数设为私有
,则您的代码将无法编译!!这是因为语义检查是在优化阶段之前完成的,这意味着编译器首先检查复制构造函数是否可访问;如果它是可访问的,那么只有优化阶段,复制构造被省略。
这被称为复制省略。< br >编译器可以进行这种优化。尽管标准没有保证这一点,但是任何商业编译器都会尽可能地执行这种优化。
标准参考:
C 03 12.8.15:
[……]在以下情况下允许省略复制操作(可组合使用以消除多个复制):
[...]
您可以使用一些编译器设置来禁用此优化,例如在gcc的情况下,从手册页中:
-fno-elide-constructor
C标准允许实现省略创建一个临时对象,该临时对象仅用于初始化相同类型的另一个对象。指定此选项将禁用该优化,并强制 G 在所有情况下都调用复制构造函数。
问题内容: Java为什么不支持C ++中的复制构造函数? 问题答案: Java。只是没有像在C ++中那样隐式地调用它们,我怀疑这是您的真正问题。 首先,复制构造函数无非是: 现在,C ++将使用以下语句隐式调用复制构造函数: 在这种情况下,克隆/复制在Java中根本没有意义,因为所有b1和b2都是引用,而不是像C 中那样的值对象。在C 中,该语句复制对象的状态。在Java中,它只是复制 引用
问题内容: 如果不可变的类对象副本将与原始副本相等,那么为什么Java 中的类具有副本构造函数?这是一个错误还是背后有原因?在Java文档中,指定了: 问题答案: 复制字符串的主要原因是为了 “修剪行李” ,即仅将底层char数组修剪为必需的字符。 基本的char数组可能太大,因为通过调用创建字符串时,char数组可以在新的字符串实例和源字符串实例之间共享;偏移量指向第一个字符,并且包括长度。 我
可能重复:< br >什么是复制省略和返回值优化? 我有以下程序: 我期望的输出如下: 但我得到以下信息: 问题是:为什么不将对象从func返回到main调用我的复制构造函数?
在上面的代码中,执行以下语句时不调用复制构造函数: 既然返回是按值的,为什么不调用复制构造函数? 谢啦
在C#中,当我创建一个空类时,它提供了一个默认的构造函数,但是当我提供一个带有参数的构造函数时,默认的构造函数不再被创建。 我的问题是: 为什么编译器不再给我默认的构造函数呢 这些问题来自于WCF,我需要默认构造函数,但也希望能够为构造函数提供值,并且不必每次都放置默认构造函数,而且我不认为未使用的默认构造函数会使很多开销。
根据我的理解,当创建了临时对象时,将调用move构造函数。这里,函数返回一个临时对象,但我的程序没有打印来自移动构造函数的消息: