《C++面向对象程序设计》三、类和对象(二)

3.4 构造函数与析构函数

构造函数

构造函数是一种特殊的成员函数,它主要用于为对象分配空间,进行初始化。构造函数的名字必须与类名相同,而不能由用户任意命名。它可以有任意类型的参数,但不能具有返回值。它不需要用户来调用,而是在建立对象时自动执行。

在建立对象的同时,采用构造函数给数据成员赋值,通常由以下两种形式

说明:

构造函数的名字必须与类名相同,否则编译程序将把它当做一般的成员函数来处理

构造函数没有返回值,在定义构造函数时,是不能说明它的类型的。

与普通的成员函数一样,构造函数的函数体可以写在类体内,也可写在类体外。

构造函数一般声明为共有成员,但它不需要也不能像其他成员函数那样被显式地调用,它是在定义对象的同时被自动调用,而且只执行一次。

构造函数可以不带参数。

成员初始化列表

在声明类时,对数据成员的初始化工作一般在构造函数中用赋值语句进行。此外还可以用成员初始化列表实现对数据成员的初始化。

**说明:**类成员是按照它们在类里被声明的顺序进行初始化的,与它们在成员初始化列表中列出的顺序无关。

带默认参数的构造函数

析构函数

析构函数也是一种特殊的成员函数。它执行与构造函数相反的操作,通常用于撤销对象时的一些清理任务,如释放分配给对象的内存空间等。析构函数有以下一些特点:

析构函数与构造函数名字相同,但它前面必须加一个波浪号(~)。

析构函数没有参数和返回值,也不能被重载,因此只有一个。

当撤销对象时,编译系统会自动调用析构函数。

**说明:**在以下情况中,当对象的生命周期结束时,析构函数会被自动调用:

如果定义了一个全局对象,则在程序流程离开其作用域时,调用该全局对象的析构函数。

如果一个对象定义在一个函数体内,则当这个函数被调用结束时,该对象应该被释放,析构函数被自动调用。

若一个对象是使用new运算符创建的,在使用delete运算符释放它时,delete会自动调用析构函数。

默认的构造函数和析构函数

如果没有给类定义构造函数,则编译系统自动生成一个默认的构造函数。

说明:

对没有定义构造函数的类,其公有数据成员可以用初始值列表进行初始化。

只要一个类定义了一个构造函数(不一定是无参构造函数),系统将不再给它提供默认的构造函数。

每个类必须有一个析构函数。若没有显示地为一个类定义析构函数,编译系统会自动生成一个默认的析构函数。

构造函数的重载

**注意:**在一个类中,当无参数的构造函数和带默认参数的构造函数重载时,有可能产生二义性。

拷贝构造函数

拷贝构造函数是一种特殊的构造函数,其形参是本类对象的引用。拷贝构造函数的作用是在建立一个新对象时,使用一个已存在的对象去初始化这个新对象。

拷贝构造函数具有以下特点:

  • 因为拷贝构造函数也是一种构造函数,所以其函数名与类名相同,并且该函数也没有返回值。
  • 拷贝构造函数只有一个参数,并且是同类对象的引用。
  • 每个类都必须有一个拷贝构造函数。可以自己定义拷贝构造函数,用于按照需要初始化新对象;如果没有定义类的拷贝构造函数,系统就会自动生成一个默认拷贝构造函数,用于复制出与数据成员值完全相同的新对象。

自定义拷贝构造函数

调用拷贝构造函数的三种情况:

  • 当用类的一个对象去初始化该类的另一个对象时;
  • 当函数的形参是类的对象,调用函数进行形参和实参结合时;
  • 当函数的返回值是对象,函数执行完成返回调用者时。

浅拷贝和深拷贝

浅拷贝,就是由默认的拷贝构造函数所实现的数据成员逐一赋值。通常默认的拷贝构造函数是能够胜任此工作的,但若类中含有指针类型的数据,则这种按数据成员逐一赋值的方法会产生错误。

上述错误是因为stu1和stu2所指的内存空间相同,在析构函数释放stu1所指的内存后,再释放stu2所指的内存会发生错误,因为此内存空间已被释放。解决方法就是重定义拷贝构造函数,为其变量重新生成内存空间。

全部评论
加油
点赞 回复 分享
发布于 2023-12-27 20:33 黑龙江

相关推荐

不愿透露姓名的神秘牛友
昨天 10:39
一个证都没 我能填什么
凉风落木楚山秋:空白不是说你没证吧,有实践也行
点赞 评论 收藏
分享
06-23 11:43
门头沟学院 Java
allin校招的烤冷...:我靠,今天中午我也是这个hr隔一个星期发消息给我。问的问题还是一模一样的😅
点赞 评论 收藏
分享
下个早班:秒挂就是不缺人
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务