从函数返回对象时调用C ++中的复制构造函数?
Posted
技术标签:
【中文标题】从函数返回对象时调用C ++中的复制构造函数?【英文标题】:Copy Constructor in C++ is called when object is returned from a function? 【发布时间】:2010-10-14 12:38:11 【问题描述】:我知道复制构造函数是在三个实例上调用的
-
在实例化一个对象并使用另一个对象的值对其进行初始化时。
按值传递对象时。
3.当一个对象按值从函数中返回时。
我对 3 号有疑问 如果在返回对象值时调用复制构造函数,如果在函数中本地声明对象,它不应该产生问题。
我的意思是复制构造函数是一个深拷贝,并且将对象的引用作为参数
【问题讨论】:
不保证在这些情况下会调用复制构造函数,因为 C++ 标准允许编译器在某些情况下优化复制 - 特别是 return value optimization @rmp251 指出的参考资料清楚地回答了这个问题。 【参考方案1】:正是为了避免问题而调用它。从本地定义的对象中初始化一个作为结果的新对象,然后销毁本地定义的对象。
在深拷贝用户定义的构造函数的情况下,都是一样的。首先为将作为结果的对象分配存储空间,然后调用复制构造函数。它使用传递的引用来访问本地定义的对象并将所需的内容复制到新对象。
【讨论】:
【参考方案2】:复制在被调用函数退出之前完成,并将当时存在的局部变量复制到返回值中。
被调用的函数可以访问返回值将占用的内存,即使在复制时该内存不在“范围内”,它仍然可用。
【讨论】:
我知道当对象值被返回时,它会首先调用复制构造函数,但是复制构造函数是用户定义的,它将引用作为参数 ClassA(const ClassA&),在这种情况下会发生什么?如果你只是返回一个引用而不是你的逻辑值会发生什么 如果函数被声明为返回一个引用返回一个局部变量的引用是一个很大的禁忌。您将返回对将在函数返回时丢弃的对象的引用。使用此参考可能会导致问题,包括粉碎。 是的,我明白这一点,所以当在返回值时调用将引用作为参数的复制构造函数时,会发生什么?它不应该也崩溃吗? 有什么问题?该函数即将返回。复制构造函数被调用。它需要对局部变量的引用。它使用此引用将所有内容复制到将用作返回值的新对象中。【参考方案3】:根据an answer我的问题,复制构造函数可能会被调用两次:一次将本地对象复制到返回“对象”,一次将返回对象复制到它被分配到的变量。
但是,它不需要!编译器可以优化这两种复制结构。
【讨论】:
我不同意你的观点。复制构造函数只在返回对象上调用一次,当将返回的对象分配给另一个外部范围对象时,调用的是赋值运算符,而不是复制构造函数。 @PeitiPeterLi - 实际上编译器可以进行任何级别的优化,我的 g++ 省略了这个语句的复制构造函数 myClass Obj=makeObj(10);这里 makeObj() 初始化一个值为 10 的对象并按值返回。 (这不是作业)【参考方案4】:不,它会在本地人被摧毁之前调用它。您可以使用记录破坏和复制构造的对象进行测试,或者查看生成的汇编代码。
【讨论】:
但是如果复制构造函数将引用作为参数(深拷贝),那么它不会复制整个对象,对吧? 取决于复制构造函数。默认的执行成员明智的复制构造。通常,您应该实现您的复制构造函数,以不依赖于传入对象的生命周期。您不必进行深度复制,但您需要确保共享的东西存在。【参考方案5】:调用复制构造函数的一般情况有以下三种:
-
在实例化一个对象并使用来自另一个对象(相同类型)的值对其进行初始化时。
按值传递对象时。
当对象按值从函数返回时。
【讨论】:
以上是关于从函数返回对象时调用C ++中的复制构造函数?的主要内容,如果未能解决你的问题,请参考以下文章