You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 13:19:59