c++ 临时对象的来源


在C++中,临时对象(Temporary Objects)通常来源于以下几种情况:

1. **隐式类型转换**:当需要将一个类型的值赋给另一个类型的变量,而这两个类型之间可以隐式转换时,编译器会生成一个临时对象来存储转换后的值。


   double d = 10; // int 到 double 的隐式转换,可能会生成临时 double 对象
   

2. **函数返回值**:当函数返回一个对象(特别是非引用类型)时,如果返回的对象不是局部静态对象或全局对象,则函数会创建一个临时对象来存储返回值,并将其返回给调用者。


   struct MyStruct {
       // ...
   };

   MyStruct createMyStruct() {
       MyStruct s;
       // ...
       return s; // 返回时,s 的一个副本(临时对象)被创建并返回
   }
   

3. **运算符重载**:在运算符重载函数中,如果返回的是对象(非引用),则可能会创建临时对象来存储运算结果。


   class Complex {
   public:
       Complex operator+(const Complex& rhs) const {
           // ...
           return Complex(/* 运算结果 */); // 创建一个临时 Complex 对象
       }
   };
   

4. **构造函数初始化列表中的隐式转换**:在类的构造函数初始化列表中,如果成员变量需要通过隐式转换来初始化,可能会创建临时对象。


   class MyClass {
   public:
       MyClass(int x) : member(x) {} // 如果 member 是另一种类型,这里可能涉及隐式转换
   private:
       SomeType member;
   };

   MyClass obj(10); // 如果 SomeType 不是 int,这里可能创建临时对象
   

5. **函数参数传递**:当函数参数是值传递(非引用或指针)时,如果传递给函数的是对象,则会在函数内部创建一个临时对象作为参数的副本。


   void func(MyStruct s) {
       // ...
   }

   MyStruct s;
   func(s); // s 的一个副本(临时对象)被传递给 func
   

需要注意的是,现代C++编译器通常会通过返回值优化(Return Value Optimization, RVO)和命名返回值优化(Named Return Value Optimization, NRVO)等技术来消除不必要的临时对象创建,以提高性能。此外,C++11及以后的版本引入了移动语义(Move Semantics)和右值引用(Rvalue References),进一步减少了临时对象的开销。