欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 类和对象(中)

类和对象(中)

2024/10/25 12:48:56 来源:https://blog.csdn.net/anjibgdexuexi/article/details/139902461  浏览:    关键词:类和对象(中)

文章目录

  • 构造函数
  • 析构函数
  • 拷贝构造函数
  • 构造和析构的执行顺序
  • 思维导图

本文主要介绍类中自动生成的构造函数,析构函数,构造拷贝函数。

构造函数

在这里插入图片描述
对于上述日期类来说,每次创建类对象的时候都需要调用初始化函数,那能不能再创建的时候就初始化完毕了呢。

构造函数是一个特殊的成员函数,它有以下几个特点:

  1. 函数名与类名相同
  2. 无返回值
  3. 对象实例化时,自动调用
  4. 支持重载函数

这里要注意构造函数与初始化函数功能类似,并不是开辟空间的作用。在这里插入图片描述如上图,我们在d1这个对象实例化的时候自动调用的构造函数,实现了赋值操作。
那如果我们不自己定义呢?
在这里插入图片描述
如上图我们发现成员变量为随机值。
下面的代码运行结果是什么呢?
在这里插入图片描述
运行结果:
在这里插入图片描述

我们可以看到,我们的年份那些变量并没有初始化,但是我们的 _t 却被调用了。
这里要说一下,C++的类型分为两种:

  1. 内置类型:int,double等等
  2. 自定义类型:class/struct等等

C++标准定义了当我们没有显式定义构造函数的时候,对于内置类型是否初始化时是没有规定的,所以这完全依靠编译器决定,而自定义类型必须初始化,如上面的 _t,它会调用 _t 的构造函数来初始化_t。当然,如果我们 Time类中并没有初始化 _a变量,那么这个内置类型也不会初始化的。

在这里插入图片描述
如上图:C++11中添加了一个补丁,那就是在写成员变量的时候,可以使用缺省参数,这样就可以让成员变量初始化了。

析构函数

默认生成的清理函数(主要是清理资源)

特点:

  1. 函数名就是类名,只不过名字前面加了个 ‘~’ 符号(按位取反符号)
  2. 无参数
  3. 不支持函数重载
  4. 对象声明周期结束后,会默认调用析构函数
    在这里插入图片描述
    当我们运行到return 0的时候,按下f11直接进入到析构函数。

拷贝构造函数

特性:

  1. 拷贝构造函数是构造函数的一个函数重载
  2. 拷贝构造函数只有一个参数,那必须是类的类型的引用如果不是的话会无限递归。
  3. 拷贝构造函数没有显式定义的时候,会生成一个默认的拷贝构造函数,不过这里的只能进行值拷贝 - C++也叫浅拷贝。

先来谈一谈第二点为什么需要传类的引用:
在这里插入图片描述

在这里插入图片描述
如上图:语法规定:当自定义类型传值传参的时候,会默认调用拷贝构造函数,如果我们的拷贝构造函数参数是 Data 类型,那么还会继续调用拷贝构造函数,解决方法就是用类的类型引用或者参数用指针接受,但是用指针接受就不是拷贝构造函数了。

在这里插入图片描述
当我们显式定义了拷贝构造函数之后,我们创建d2对象之后,会默认调用我们的拷贝构造函数。那如果我们不写呢?
在这里插入图片描述
我们发现,即使我们不自己定义,编译器默认生成的也可以,那我们就不需要自己写了吗?来看一下我们的栈:
在这里插入图片描述

  • 可以看到,当我们没有写拷贝构造函数的时候,编译器默认生成的为浅拷贝,它是直接把st1的地址拷贝给st2,所以当我们运行结束后调用析构函数就调用了两次,不过这里是先调用的st2的析构函数(后面再说),所以当我们的st1调用析构的时候,此时我们的st1的_a和st2的_a是同一快空间,我们再free一遍肯定要报错的,free了一片已经free得空间,就相当于下面这种情况[doeg]:
    在这里插入图片描述
    所以当我们有想 stack的 _a,这种资源类型时(动态开辟等等),我们就必须自己写一个拷贝构造函数了。(深拷贝)
    深拷贝实现:
//这里加const的原因就是,防止写错,例如把类里面的值拷贝到st里面(写反了)Stack(const Stack& st){_a = (int*)malloc(sizeof(int) * st._capacity);if (_a == nullptr){printf("malloc fail!\n");exit(-1);}memcpy(_a,st._a,sizeof(int)*(st._size));_size = st._size;_capacity = st._capacity;}

在这里插入图片描述

构造和析构的执行顺序

在这里插入图片描述

构造函数的执行顺序就是你先写谁先执行。

析构函数的执行顺序则是:先局部你后写的反而先析构,然后再是全局的,全局也是后写的先析构
在这里插入图片描述
析构顺序
在这里插入图片描述
注意:析构的顺序,当局部有静态类的时候,它的生命周期是到程序结束的时候才结束,所以即使他存在局部域,也是在程序结束的时候才调用析构的。

思维导图

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com