首页 > 编程语言 >C++临时对象

C++临时对象

时间:2024-02-28 15:55:55浏览次数:28  
标签:类型转换 arr const 函数 临时 C++ 对象

C++临时对象

临时对象的构造与析构

在 C++ 中,临时对象(Temporary Object)是在表达式求值过程中创建的、无名字的对象。它们通常用于存储中间结果或作为函数调用的参数或返回值,其生命周期通常仅限于表达式的求值过程中。

临时对象的构建和析构与普通对象类似,只是它们的生命周期通常比较短暂,且没有命名。在 C++ 中,临时对象的构建和析构过程如下:

  • 构建(构造函数):当创建一个临时对象时,编译器会调用相应的构造函数来初始化该对象的成员变量。构造函数负责为对象分配内存并对其进行初始化。临时对象的构建过程与普通对象一样,只是没有显式地使用对象名字而已。
  • 析构(析构函数):临时对象的生命周期通常是在表达式求值结束后立即结束,因此它们的析构函数会在对象销毁时被调用。析构函数负责释放对象所占用的内存空间,以及执行其他必要的清理工作。与构造函数类似,析构函数的调用也是由编译器自动完成的,无需手动介入。

为什么要关注临时对象

关注临时对象是有意义的,因为它们可能会对代码的性能和行为产生影响。以下是一些关于临时对象的重要注意事项:

  1. 性能问题:在频繁创建临时对象的情况下,可能会导致不必要的开销,降低程序性能。避免不必要的临时对象可以提高性能。
  2. 资源管理:如果临时对象持有资源(例如动态分配的内存),需要确保它们在不再需要时被妥善释放,以避免资源泄漏。
  3. 副作用:某些情况下,临时对象的创建可能导致意外的副作用,这需要额外的注意。

临时对象的使用场景

  1. 函数返回值:当函数需要向外返回一个内部对象时,编译器需要创建一个临时对象来存储返回值,因为内部对象无法返回,所以用该内部对象来初始化该临时变量。调用方使用完该临时对象后立即销毁。比如:

    #include <iostream>
    using namespace std;
    
    template <typename T>
    class DynamicArrary {
    public:
    	 explicit DynamicArrary(int size):
    		 m_size{ size }, m_arrary{ new T[size] }{
    		 cout << "Constructor: dynamic array is created!\n";
    	 }
    
    	 virtual ~DynamicArrary() {
    		 delete[] m_arrary;
    		 cout << "Destructor: dynamic array is destroyed!\n";
    	 }
    
    	 //复制构造函数
    	 DynamicArrary(const DynamicArrary& rhs) : m_size{ rhs.m_size } {
    		 m_arrary = new T[m_size];
    		 for (int i = 0; i < m_size; ++i)
    			 m_arrary[i] = rhs.m_arrary[i];
    		 cout << "Copy constructor: dynamic array is created!\n";
    	 }
    
    	 //复制赋值操作符
    	 DynamicArrary& operator=(const DynamicArrary& rhs) {
    		 cout << "Copy assignment operator is called!\n";
    
    		 if (this == &rhs)
    			 return *this;
    		 delete[] m_arrary;
    		 m_size = rhs.m_size;
    		 m_arrary = new T[m_size];
    		 for (int i = 0; i < m_size; ++i)
    			 m_arrary[i] = rhs.m_arrary[i];
    		 return *this;
    	 }
    
    	 //索引运算符
    	 T& operator[](int index) {
    		 //不进行边界检查
    		 return m_arrary[index];
    	 }
    
    	 const T& operator[](int index) const {
    		 return m_arrary[index];
    	 }
    
    	 int size() const { return m_size; }
    private:
    	T* m_arrary;
    	int m_size;
    		
    };
    
    //生产int动态数组的工厂函数
    DynamicArrary<int> arrayFactor(int size) {
    	DynamicArrary<int> arr{ size };
    	return arr;
    	//由于arr是内部对象,无法向外传递,所以返回的是一个临时对象,
    	//这个临时对象需要内部对象arr来初始化,由于这个动态数组arr即将消亡,
    	//所以是右值,那么在构建临时对象时,会调用 复制构造函数(没有右值的版本, 但是右值可以传递给const左值引用参数)
    }
    
    int main()
    {
    	DynamicArrary<int> arr = arrayFactor(10);
    	
    	return 0;
    }
    

    main函数中调用arrayFactor()函数就会导致返回临时对象。

  2. 函数参数传递:临时对象可以作为函数的参数(以传值的方式)传递给函数。例如:

    void showArraySize(DynamicArrary<int> arr){
        std::cout << arr.size() <<endl;
    }
    
    int main(){
        showArraySize(DynamicArrary<int>(10)); //传递临时对象作为参数
        
        return 0;
    }
    
  3. 表达式求值:在表达式求值过程中,可能会生成临时对象。例如:

    MyClass obj1(10);
    MyClass obj2(20);
    MyClass obj3 = obj1 + obj2; // 表达式 obj1 + obj2 会生成临时对象
    
  4. 类型转换: 临时对象常用于类型转换。当您执行显式或隐式类型转换时,临时对象用于保存转换后的值。

    • 显示类型转换:

      double result = static_cast<double>(5); // 创建临时 double 对象进行类型转换
      
    • 隐式类型转换:

      void printFunc(const string&){  //注意const
          cout << string <<endl;
      }
      
      char *buf = "xxxx";
      printFunc(buf);  //发生隐式类型转换
      

      在调用printFunc()函数时,编译器首先会产生一个string类型的临时变量,该临时变量将buf转为string类型,然后传递给函数参数,直到函数返回,该临时变量才被销毁。

      注意:只有当参数类型为const,或者传值方式时,才能进行隐式类型转换,非const的传引用方式不能进行隐式类型转换。这是因为隐式类型转换生成的临时变量是右值,只有const类型的参数引用即可以接收左值,也可以接收右值,而非const类型的参数引用无法接收右值。

标签:类型转换,arr,const,函数,临时,C++,对象
From: https://www.cnblogs.com/weikongtao/p/18040671

相关文章

  • C++ 点的线性拟合 y(x)=ax+b
    一、简单分析点的线性拟合是一般实验数据处理最常用的方法。下面考虑一个用n个数据点拟合成直线的问题,直线模型为y(x)=ax+b这个问题称为线性回归。设变量y随自变量x变化,给定n组观测数据(xi,yi),用直线来拟合这些点,其中a,b是直线的斜率和截距,称为回归系数。为确定......
  • 微软 官方 .net 组件 下载 directx组件 下载 viual c++ 组件 下载 官方 修复DLL方
    下载.NETFramework|免费官方下载(microsoft.com).NETFramework是仅适用于Windows版本的.NET,用于生成客户端和服务器应用程序。升级应用在VisualStudio中单击几下即可将应用从.NETFramework升级到最新的.NET。  DownloadDirectXEnd-UserRuntimefromO......
  • Python面向对象,类属性,实例属性,类方法,实例方法,静态方法的区别及用法详解
    一.前言在Python的面向对象编程中,类属性和实例属性是两个不同的概念,它们在作用域和使用方式上有所区别。在Python中的面向对象编程中有三种方法:实例方法、类方法和静态方法,它们之间的差异主要体现在参数传递和调用方式上。二.面向对象-类属性和实例属性1.区别在Pyth......
  • nginx支持cgi(c,c++)
    前段时间用我修改了tinyhttpd,让其cgi支持文件流,感觉满小巧,就应用上了。最近访问请求量上来而来,它对socket的各种异常状态处理不好,对于慢速的链接会占用我的线程。虽然我一直想仿出tencentwebproxy,可惜人懒且没空。用用nginx也不错,配置其支持fcgi,应用代码稍微改改就支持了,效果很不......
  • c++的oop之class和struct
    c++中的面向对象构造函数与C#一样,可以拥有多个构造函数,但python只有一个构造函数默认的无参构造函数,可以这样写classname()=default;构造函数时初始化变量,建议这样写。对于const或自定义类型必须这样写,而对于内置类型几乎是一样的。MyClass::MyClass(stringname,intid):......
  • C++多态
    /**多态/动态调用***1.虚函数/虚拟函数*语法:在函数前面加上virtual**1.1虚函数与虚继承没有关系,只是共用了关键字**2.重写/覆盖:虚函数且函数名字类型等完全一样*$注:虚函数是覆盖,不是虚函数才构成隐藏*$重写:指对函数体重写,函数体外的是直接使用父类的,......
  • C++继承
    //继承/***继承受权限影响*有publicprotectedprivate三种继承**基本语法:*classstudent:publicPerson*{**详细:跳转20inheritance--C++NO.23--3_27**///继承和组合/***组合即为在类成员是其他自定义类型:如适配器中栈,队列,反向迭代器.**继......
  • C++ STL 容器 forward_list类型
    C++STL容器forward_list类型介绍std::forward_list是C++标准模板库(STL)中的一个单向链表容器。与std::list不同,std::forward_list只允许从头部到尾部的单向迭代,不支持反向迭代。因此,std::forward_list在某些操作上可能比std::list更高效,尤其是在插入和删除元素时......
  • 从面向对象的角度看集合类,以List<String> list = new ArrayList<>()为例
    心血来潮琢磨了这么一个问题:Listlist=newArrayList<>();这句代码挺常用的,但是如果要从面向对象的角度去讲讲这句代码背后的逻辑,该怎么讲?好像真不容易一口气说完整,于是便有了本文的梳理。从关系图我们可以知道,ArrayList继承自一个抽象类AbstractCollection,它们都实现了Lis......
  • 4-request对象
    前端提交数据必备知识点前端form表单中action属性,不写默认是当前路由地址前端form表单中的method属性,不写默认是GET请求前端页面templates\register.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>注册页面</title>......