-
-
[分享]C++基础十-构造函数和析构函数
-
2021-9-1 18:05 3658
-
构造函数
在类中,有一种特殊的成员函数,它的名字和类名相同,没有返回值,不需要用户显式调用,用户也不能调用,而是在创建对象时自动执行,这种特殊的成员函数就是构造函数。构造函数的作用是在创建对象时进行初始化工作,最常见的就是初始化成员变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #include <iostream> using namespace std; class CStudent { public: / / 默认构造函数 / / CStudent(); / / 使用默认参数的默认构造函数 CStudent(char * szName = (char * ) "xiaoxin" , int nScore = 9 ); / / 使用初始化列表的重载构造函数 CStudent( int nID, char * szName, double nScore); / / 拷贝构造函数 CStudent(const CStudent& student); / / 析构函数 ~CStudent(); void ShowInfo(); public: int m_nID = 0 ; char m_szName[ 128 ] = { 0 }; double m_nScore = 0 ; }; CStudent::CStudent(char * szName, int nScore) { m_nID = 1 ; strcpy_s(m_szName, szName); m_nScore = nScore; } CStudent::CStudent( int nID, char * szName, double nScore) :m_nID(nID), m_nScore(nScore) { strcpy_s(m_szName, szName); } CStudent::CStudent(const CStudent& student) { m_nID = student.m_nID; strcpy_s(m_szName, student.m_szName); m_nScore = student.m_nScore; } CStudent::~CStudent() { cout << "~CStudent" << endl; } void CStudent::ShowInfo() { cout << "ID=" << m_nID << endl; cout << "Name=" << m_szName << endl; cout << "Score=" << m_nScore << endl; } int main() { CStudent StudentA; StudentA.ShowInfo(); CStudent StudentB( 2 , (char * ) "xiaobai" , 8 ); StudentB.ShowInfo(); CStudent StudentC(StudentB); StudentC.ShowInfo(); return 0 ; } |
默认构造函数
默认构造函数指的是一个能被无参调用(包含参数有默认值的函数)的函数,包括自己定义的默认构造函数和编译器合成的默认构造函数。如果类中没有定义任何构造函数,那么编译器会自动合成一个默认的构造函数,只是这个构造函数的函数体是空的,也没有参数,不执行任何操作。
重载构造函数
和普通成员函数一样,构造函数是允许重载的。一个类可以有多个重载构造函数,创建对象时根据传递的实参来判断调用哪一个重载构造函数,重载构造函数一般用来初始化类的成员变量。
初始化列表
1、初始化成员变量,可以在构造函数的函数体中对成员变量赋值,还可以采用初始化列表。
2、初始化列表可以用于全部成员变量,也可以只用于部分成员变量。
3、成员变量的初始化顺序与初始化列表中的变量顺序无关,只与成员变量在类中声明的顺序有关。
4、构造函数初始化列表还有一个重要的作用,那就是初始化const 成员变量。初始化const 成员变量的唯一方法就是使用初始化列表。
5、初始化列表在构造函数执行前执行。初始化是指变量在创建的同时获得的初始值,赋值是变量定义后的操作,效果是改变变量的值。
深拷贝和浅拷贝
- 所谓浅拷贝,指的是复制对象时,只对对象中的数据成员进行简单的赋值。
- 所谓深拷贝,指的是复制对象时,对于对象中的动态成员,并不只是简单的赋值,而是重新分配内存空间,即资源重新分配。
- 如果一个类对象中有指针成员变量,在进行对象拷贝时,浅拷贝会使得新的对象的指针所指向的地址和被拷贝对象的指针所指向的地址相同,当delete对象时会导致两次重复delete该指针而出错,所以此时应该使用深拷贝。
拷贝构造函数
拷贝构造函数是一种特殊的构造函数,具有单个形参,该形参(常用const修饰)是对该类型的引用。若类中没有显式定义拷贝构造函数,系统会创建一个默认拷贝构造函数,默认拷贝构造函数执行的是浅拷贝。
类的对象需要拷贝时,拷贝构造函数将会被调用,以下情况都会调用拷贝构造函数:
- 一个对象以值传递的方式传入函数体
- 一个对象以值传递的方式从函数返回
- 一个对象需要通过另外一个对象进行初始化
当类中有指针类型的成员变量,或者有成员在构造函数中分配了其他资源,必须显式定义拷贝构造函数,并且实现深拷贝。
析构函数
析构函数也是一种特殊的成员函数,没有返回值,不需要程序员显式调用,程序员也没法显式调用,而是在销毁对象时自动执行。析构函数的名字是在类名前面再加一个~ 符号。析构函数没有参数,不能被重载,因此一个类只能有一个析构函数。如果类中没有定义,编译器会自动生成一个默认的析构函数。
创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用析构函数来进行清理工作,例如释放分配的内存、关闭打开的文件等。