类和对象【二】this指针,构造函数和成员初始化列表【超详细】

server/2024/12/23 6:09:54/

文章目录

  • this指针
    • this指针的定义
    • this指针的“工作”原理
    • this指针的作用
    • this指针的特点
  • 构造函数
    • 构造函数的定义
    • 构造函数的作用
    • 构造函数的特点
    • 构造函数的调用方式
      • 括号法
        • 无参构造或者全缺省构造
        • 需要传参才能调用的构造函数
      • 隐式类型转换法
        • 是只传一个参数就能调用的构造函数
        • 是要传多个参数才能调用的构造函数
  • 成员初始化列表
    • 成员初始化列表的位置和语法
    • 成员初始化列表的特点
    • 总结

this指针

this指针的定义

C++编译器给每个非静态的成员函数增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),这个指针就是this指针
在函数体中所有“成员变量”的操作,都是通过该指针去访问。
只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成


this指针的“工作”原理

任何一个对象调用成员函数的时候
编译器都会隐式地把这个对象的地址也作为参数传递给成员函数,在成员函数的参数表中也隐藏着一个形参this,这个this就接收了编译器传递的调用成员函数的对象的地址

类似下图
在这里插入图片描述

只不过上述过程都由编译器自己完成,而且是隐式地完成
程序员看不见,也不能由程序员主动完成,会报错


this指针的作用

通过我的上一篇文章我们能知道:成员函数不是存储在对象中,而是存放在公共代码区

但是任何一个类实例化出的对象都能调用该类的成员函数,那么成员函数如何知道是哪一个对象在调用它呢?

  • 通过this指针就可以知道是哪一个对象在调用成员函数了,因为this指针指向了调用这个成员函数的对象

  • this指针是const修饰的指针,指向了调用成员函数的对象,那么this指针除了不能改变指向以外,所有的指针操作它都可以使用【例如 解引用,以及通过操作符 -> 使用对象的成员】

  • this指针可以区分成员函数中与对象的成员变量同名的变量,即this指针指向的那一个是成员变量

    在这里插入图片描述
    在这里插入图片描述


this指针的特点

  1. this指针的类型:类 类型* const,即成员函数中,不能改变this指针的指向

  2. this指针本质上是“成员函数”的形参,当对象调用成员函数时,编译器将对象地址作为实参传递给
    this形参【程序员不能显示传递】。所以对象中不存储this指针。

  3. 只能在“成员函数”的内部使用,因为this指针是形参,出了成员函数作用域就销毁了


构造函数

构造函数的定义

在创建对象时调用的特殊方法。其主要作用是给对象的成员赋值
在C++中,构造函数通常没有返回类型,并且不能被声明为const
在创建类的对象时,构造函数自动被调用
此外,构造函数可以重载,即可以有多个名字相同的构造函数,但参数列表必须不同。


构造函数的作用

主要作用:给存储在对象中的成员变量赋初值【注意:赋初值是赋值,不是初始化,初始化只能在定义时初始化一次,之后的改变成员的值都是赋值

次要作用:由于构造函数是实例化对象时,编译器自动调用

可以根据这个特点,在构造函数中添加初始化以外的操作【例如记录一下调用了多少次构造函数等】,根据需求自定


构造函数的特点

  1. 实例化对象时,编译器自动调用对应构造函数

  2. 构造函数名必须类名相同

  3. 构造函数没有返回值void也不用写

  4. 构造函数可以重载

    在这里插入图片描述

  5. 构造函数可以参数缺省

    在这里插入图片描述

  6. 如果类中没有显式定义的构造函数,编译器会自动生成一个默认的构造函数【如果显式定义了,就不会有这个默认构造函数了
    编译器给的默认构造函数:
    没有参数
    对内置类型(int ,char等)一般有的编译器可能初始化成0不做处理就是不初始化,让它还是随机值
    对自定义类型(类,结构体等)就调用它这个类型自己的默认构造【默认构造 即 不需要传参数就可以调用的构造函数,例如无参构造和全缺省的构造函数

    在这里插入图片描述
    C++11针对编译器给的默认构造内置类型不做处理的问题做出了一个优化:可以在类中内置类型声明时给它缺省值
    给了缺省值之后,编译器在调用构造函数之前就会用缺省值给内置类型的成员初始化

    在这里插入图片描述


构造函数的调用方式

括号法

无参构造或者全缺省构造

调用无参构造或者全缺省构造直接实例化对象就行
语法:类名 对象名

在这里插入图片描述
注意:
调用无参构造或者全缺省构造不要打空括号

因为
类名+标识符+()可以是一个返回值是类的对象的函数的声明

如果实例化对象的时无参构造也或者全缺省构造+()就区分不开

在这里插入图片描述

所以规定调用无参构造或者全缺省构造不要打空括号

在这里插入图片描述

需要传参才能调用的构造函数

语法; 类名 + 对象名+(参数表)


在这里插入图片描述

隐式类型转换法

是只传一个参数就能调用的构造函数

语法:== 类名 + 对象名 = 参数==
参数的类型必须与构造函数的形参类型一致

在这里插入图片描述


是要传多个参数才能调用的构造函数

语法: 类名 + 对象名 = {参数1,参数2,………}
参数的类型必须与构造函数的形参类型一致


在这里插入图片描述

原理:
语法上:
编译器使用 赋值操作符(=)的右操作数调用了构造函数构造出了一个临时对象再用这个临时对象拷贝构造出了目标对象

实际上:
编译器会在语法实现上做出优化
直接使用赋值操作符(=)的右操作数调用了构造函数构造出了目标对象


成员初始化列表

如果说类里写的是成员的声明,那么成员初始化列表就是成员定义初始化的地方


成员初始化列表的位置和语法

构造函数实现的()之后,构造函数的函数体之前

语法:
:+成员名+(要初始化成的东西),成员名+(要初始化成的东西)………


在这里插入图片描述


成员初始化列表的特点

  1. 成员初始化列表中只初始化存储在对象中的成员

  2. 每个成员只能在成员初始化列表中出现一次【成员初始化列表就是成员定义初始化的地方==,因为初始化只能初始化一次

    在这里插入图片描述

  3. 成员初始化列表初始化的顺序不是在成员初始化列表中成员变量出现的顺序
    成员变量在类中声明的顺序才是成员初始化列表初始化的顺序

    在这里插入图片描述

  4. 其他自定义类型的对象成员变量默认构造是在成员初始化列表中调用的【无论成员初始化列表中有没有写都会调用

  5. 以下成员变量必须在成员初始化列表中初始化
    1 引用成员变量【因为引用必须初始化
    2 const修饰的成员变量【因为被const修饰之后就不能被改变了,所以只能在初始化的时候赋初值
    3 其他自定义类型且没有默认构造的对象【因为没有默认构造,编译器就不能自动调用构造函数了,而给构造函数传参只能在定义初始化时传递

  6. 类中声明的成员变量的缺省值其实是传给成员初始化列表的,因为是缺省值,所以如果对应成员变量在成员初始化列表中已经有值了,就不会再用缺省值了

    在这里插入图片描述


总结

综上:成员初始化列表比构造函数更有优势

所以赋初值尽量使用成员初始化列表


以上就是本篇文章的全部内容了,如果对你有帮助的话,可以点赞收藏支持一下吗


http://www.ppmy.cn/server/4351.html

相关文章

Springboot集成Ehcache3实现本地缓存

如果只需要在单个应用程序中使用本地缓存&#xff0c;则可以选择Ehcache&#xff1b;它支持内存和磁盘存储&#xff0c;这里不以注解方式演示&#xff0c;通过自己实现缓存管理者灵活控制缓存的读写&#xff1b; 1、引入相关依赖 <!-- ehcache3集成start --><depende…

JVM之JVM栈的详细解析

Java 栈 Java 虚拟机栈&#xff1a;Java Virtual Machine Stacks&#xff0c;每个线程运行时所需要的内存 每个方法被执行时&#xff0c;都会在虚拟机栈中创建一个栈帧 stack frame&#xff08;一个方法一个栈帧&#xff09; Java 虚拟机规范允许 Java 栈的大小是动态的或者是…

K8s RBAC认证授权深度解析

​ &#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、k8s简介 2、RBAC简介 二、RBAC…

PSCAD|应用于输电线路故障测距的行波波速仿真分析

1 主要内容 该程序参考文献《应用于输电线路故障测距的行波波速仿真分析》&#xff0c;利用线路内部故障产生的初始行波浪涌达线路两端测量点的绝对时间之差值计算故障点到两端测量点之间的距离&#xff0c;并利用小波变换得到初始行波波头准确到达时刻&#xff0c;从而精准定…

安装kafka需优先安装 zookeeper ,scala

安装kafka需优先安装 zookeeper ,scala scala安装&#xff08;如安装略过&#xff09; 现在 wget https://downloads.lightbend.com/scala/2.12.11/scala-2.12.11.tgz解压 tar -zxvf scala-2.12.11.tgz编辑环境变量 vim /etc/profile添加环境变量 &#xff08;export SCALA_H…

安卓Dagger框架:依赖注入实践与应用

摘要 Dagger是适用于Android和Java生态系统的强大依赖注入(Dependency Injection, DI)工具&#xff0c;以其编译时生成代码和高效的运行时性能而著称。本文旨在深入探讨Dagger的核心概念、工作流程、优缺点以及实际代码示例&#xff0c;以便开发者更好地理解并有效利用这一框架…

JVM-内存模型(运行时数据区)

目录 1. 线程私有1.1 程序计数器&#xff08;PC寄存器&#xff09;1.2 虚拟机栈1.3 本地方法栈 2. 线程共享2.1 堆2.2 方法区 3. 直接内存 参考 pdai全栈知识体系-JVM-内存结构 1. 线程私有 1.1 程序计数器&#xff08;PC寄存器&#xff09; 作用&#xff1a;PC 寄存器用来存…

3.2 iHRM人力资源 - 组织架构 - 编辑及删除

iHRM人力资源 - 组织架构 文章目录 iHRM人力资源 - 组织架构一、编辑功能1.1 表单弹层并数据回显1.2 编辑校验1.3 编辑 二、删除功能 一、编辑功能 编辑功能和新增功能用的组件其实是一个&#xff0c;结构几乎是一样的&#xff0c;其实是复用了组件&#xff0c;我们也省去了很…