C++传值传参时拷贝构造与临时对象创建的疑问
问题解答:函数返回时临时对象的作用
给定代码
#include <iostream> #include <vector> #include <cstring> class Person { public: Person(const char *i_Name = "Unknown", int i_Age = 0) : m_Name(copyFromTo(i_Name, m_Name)), m_Age(i_Age) { std::cout << "creating obj " << this << ".\n"; } Person(const Person &other) { std::cout << "Copying from " << &other << " to " << this << ".\n"; this->m_Name = copyFromTo(other.m_Name, this->m_Name); this->setAge(other.m_Age); } ~Person() { std::cout << "destroying obj " << this << ".\n"; if (m_Name) { delete[] m_Name; } } void printDetails() { std::cout << "Hello, my name is " << m_Name << " and I am " << m_Age << " years old.\n"; } void setAge(int i_Age) { m_Age = i_Age; } int getAge() const { return m_Age; } private: char *copyFromTo(const char *i_Source, char *i_Destination) { int sourceSize = strlen(i_Source); i_Destination = new char[sourceSize + 1]; memcpy(i_Destination, i_Source, sourceSize); i_Destination[sourceSize] = '\0'; return i_Destination; } char *m_Name; int m_Age; }; Person birthday(Person person) { std::cout << "person's address inside the function " << &person << ".\n"; person.setAge(person.getAge() + 1); return person; } int main() { Person person = {"New Person", 24}; birthday(person); std::cout << "END OF PROGRAM.\n"; }
运行输出
creating obj 0x61fea8. Copying from 0x61fea8 to 0x61feb8. person's address inside the function 0x61feb8. Copying from 0x61feb8 to 0x61feb0. // [临时对象创建] destroying obj 0x61feb0. // [临时对象销毁] destroying obj 0x61feb8. END OF PROGRAM. destroying obj 0x61fea8.
问题
调用birthday函数时,因参数按值传递创建了局部person对象;但函数结束返回时,又调用拷贝构造函数创建了一个临时对象,且该临时对象在局部person对象销毁前就被销毁。请问为何需要这个临时对象?它的实际作用是什么?
解答
这个临时对象是C++按值返回机制的必然产物:函数内部的局部person对象(地址0x61feb8)属于函数栈帧,函数执行完毕后栈帧会被销毁,局部对象的内存也会被释放,根本没法直接把它的内容交给调用者。
所以当birthday返回person时,必须先把这个局部对象的内容拷贝到临时对象里(地址0x61feb0)——这个临时对象位于调用者的上下文内存区域,生命周期由调用方管理。
在你的代码里,这个临时对象创建后没有被任何变量接收,所以它刚完成“中转返回值”的使命就被销毁了,之后才轮到函数的局部对象被销毁。
总结来说,它的核心作用就是作为返回值的中转载体:把即将消失的局部对象的内容传递到调用者的上下文里,哪怕调用者没接住这个返回值,这个中转流程也得执行(除非编译器触发了返回值优化RVO来省略临时对象)。
内容的提问来源于stack exchange,提问作者Yarin0600
相关产品推荐
相关产品推荐

