类的6个默认成员函数:如果一个类中什么成员都没有,简称为空类。
空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。
默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
在现实生活中,可能存在一个与你一样的自己,我们称其为双胞胎。
那在创建对象时,可否创建一个与已存在对象一某一样的新对象呢?
拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const
修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。
C++拷贝构造函数是一种特殊的构造函数,用于创建对象时,使用一个已有对象的内容来初始化新的对象。它接受一个同类对象作为参数,并按照该对象的数据成员的值来创建新的对象。
拷贝构造函数通常用于以下情况:
拷贝构造函数的定义形式为:
其中,类名是要创建的对象的类名,obj
是要拷贝的对象。
拷贝构造函数的工作原理是将obj
的数据成员的值复制给新创建的对象。这意味着新对象的数据成员会与原对象具有相同的值,但是它们是独立的,改变其中一个对象的数据成员的值不会影响另一个对象的数据成员。
如果没有显式定义拷贝构造函数,编译器会提供一个默认的拷贝构造函数。默认的拷贝构造函数执行的是浅拷贝,即简单地将原对象的值复制给新对象的数据成员。如果类中包含指针类型的数据成员,需要自己定义拷贝构造函数,进行深拷贝,确保指针指向的对象也被复制。
注意,拷贝构造函数是类成员函数,通常定义在类的公有部分。拷贝构造函数是通过对象名来调用的,而不是通过函数名来调用。
拷贝构造函数也是特殊的成员函数,其特征如下:
注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。
注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝。
为了提高程序效率,一般对象传参时,尽量使用引用类型,返回时根据实际场景,能用引用尽量使用引用。
除了下面这种写法外
我们还可以写成,这种写法也是拷贝构造
Date
(日期类)MyQueue
Stack
Queue
List
等关于下面代码的展示,VS2022编译器可能显示不出来,因为编译器等级比较高,像下面的情况,编译器会自行优化,使代码运行效率更高,致使本来的结果显示不出来。
传址返回会生成Date d
的临时拷贝进行返回
引用返回会直接返回Date d
的地址,而不会进入临时拷贝
出了函数作用域之后会调用析构函数,致使结果为-1,此时的ref
类似野指针
依次类推,我们再定义一个fx()
函数,在fx()
函数的空间里存放一些变量,ret空间里的内容会被fx()
函数里的内容给覆盖
当出了作用域,返回对象还在没有析构,那就可以用引用返回,减少拷贝,比如用static
修饰
Date operator=
运用的下篇文章赋值运算符重载,可以看到传值和传址在遇到不同问题时有不同的表现,如下,在运算符重载的问题下,传址调用比传值调用的效率更高
返回对象是一个局部对象或临时对象,出了当前func
函数作用域,就析构销毁了,那么不能用引用返回,用引用返回时存在风险的,因为引用对象在func
函数栈帧已经销毁了
虽然引用返回可以减少一次拷贝,但是出了函数作用域,返回对象还在,才能用引用返回
即下述情况