默认成员函数:析构、深浅拷贝

析构函数

析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。

特性

  1. 析构函数名时在类名前面加上字符~
CPP 复制代码
class Date
{
public:
	Date(int year, int month , int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	~Date()
	{
		......
	}
	
private:
		int _year = 0;
		int _month = 0;
		int _day = 0;
}
  1. 无参数无返回值类型,不带void

  2. 一个类只能由一个析构函数,如果未显式定义,系统会自动生成默认的析构函数。

  3. 析构函数不支持重载。

  4. 对象声明周期结束时,C++编译系统自动调用析构函数。

  5. 编译器生成的默认析构函数,对自定义类型成员调用它的析构函数。对内置类型不做处理。

  6. 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数。有资源申请时,一定要写,否则会造成资源泄露。

    对象的栈帧的开辟和销毁都是由编译器进行的。不需要析构

    动态开辟的空间资源才需要析构。

拷贝构造

拷贝构造函数:只有单个形参,该形参试对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。

特征

  • 浅拷贝:值拷贝
  • 深拷贝:深拷贝本质拷贝指向的资源,让两个被拷贝和拷贝者都有一样大的空间,一样大的值,但不是同一个空间。
  1. 拷贝构造函数是构造函数的一个重载形式

  2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。

  3. 若未显式定义,编译器会生成默认的拷贝构造函数。默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。

  4. 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝,还需要自己显实现吗?如果像日期类这种类没有必要的,但是如果是别的需要开辟空间的呢?

    创建一个stack的对象s1,s1调用构造函数,申请了一个空间。s2使用s1拷贝构造,而Stack中没有显式定义的拷贝构造函数,此时编译器默认生成了一个拷贝构造函数,默认的拷贝构造函数是按照值拷贝的方式进行拷贝的,即将s1中的成员变量存储的值原封不动的赋值给了s2中的成员变量,拷贝结束之后,s2中的成员变量指向了和s1成员变量指向的同一片空间。

    当程序结束的时候,s2先销毁,s1后销毁,s2先调用析构函数对这片申请的空间进行了析构,然后s1销毁,此时s1并不知道这片内存空间已经销毁了,再次对这片空间进行了析构,此时就会崩溃。对一片内存空间进行了多次释放。

浅拷贝

  • 类中如果没有设计资源申请时,拷贝构造函数是否写都可以;
  • 一旦涉及到资源申请,则拷贝构造函数是一定要写的,否则就是浅拷贝。
  1. 拷贝构造的典型调用场景:
    • 使用已存在的对象创建对象
    • 函数参数类型未类类型对象
    • 函数返回值类型为类类型对象
  • 为了提高程序效率,一般对象传参时,尽量使用引用类型,返回时根据实际场景,能用引用尽量使用引用。

  • 拷贝构造主要用于解决深拷贝的问题。

  • 深拷贝本质拷贝指向的资源,让两个被拷贝和拷贝者都有一样大的空间,一样大的值,但不是同一个空间。

深拷贝

CPP 复制代码
//Stack st2(st1);
Stack(const Stack& st)
{
	_a = (int*)malloc(sizeof(int) * st._capacity);
	if(_a == nullptr)
	{
		perror("malloc fail");
		exit(-1);
	}
	memcpy(_a,st._a,sizeof(int)*st._top);
	_top = st._top;
	_capacity = st._capacity;
}
  • 两个已经存在的对象拷贝,赋值拷贝
  • 一个已经存在的对象拷贝初始化另一个要创建的对象,就是拷贝构造
CPP 复制代码
A aa1(1);

A aa2(aa1);    //拷贝构造
A aa3 = aa1;   //拷贝构造

aa2 = aa3;    //赋值拷贝
相关推荐
hi_ro_a26 分钟前
基于正倒排索引的boost搜索引擎
linux·c++·搜索引擎·项目
有Li31 分钟前
【AI答疑】MR数据预处理步骤
人工智能·笔记·算法·语言模型·医学生
神仙别闹37 分钟前
基于 C++ MFC 实现的个人通讯录管理系统
c++
GG-_-Bond43 分钟前
9.1kv存储持久化模拟面试
linux·c语言·数据结构·c++
江湖人称菠萝包1 小时前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter3-Qt类库概述
笔记·qt·qt5
郝学胜-神的一滴2 小时前
C++20模板元编程 04:变量模板 别名模板与模板Lambda实战
服务器·开发语言·数据结构·c++·程序人生
江屿风2 小时前
【Linux系统】【Linux进程终止等待详解与程序替换机制初体验】流食般投喂
linux·运维·笔记·系统架构·centos·unix
qq_344920562 小时前
Qt事件过滤器
开发语言·c++·qt
码匠许师傅2 小时前
【C++三方组件】fmt:C++字符串格式化的前世今生
c++
anew___2 小时前
舵机——让 Arduino 动起来
c++·stm32·单片机·嵌入式硬件·c