首页 > 其他分享 >Cpp中的this指针--复习记录

Cpp中的this指针--复习记录

时间:2024-08-08 22:25:37浏览次数:13  
标签:复习 -- 函数 对象 static Cpp 成员 变量 指针

1.什么是this指针?

    每个类都有一个this指针,我们的非静态成员函数可以通过这个this指针来操作对象的成员属性。this指针存储的就是类的实例的地址,this指针时时刻刻指向的都是这个实例对象本身。

由下图可知:

我在主函数中栈上创建了一个类的实例(由操作系统自动回收释放),然后再用s调用learn打印出当前this指针的地址,由终端可见,此时类对象地址与this指针的地址是相同的。

这样我们知道了this指针的基本概念,再来说说他的具体用途:

 1.当形参和成员变量同名时

可以用this指针来区分。如下图所示 ,这样就可以将传入的sum值赋值给类的成员变量。

2.在类的非静态成员函数中返回对象本身,可以使用return *this来返回当前对象的引用,这种技术被称为链式调用(chaining),它允许在调用对象的成员函数后,直接继续调用另一个函数。

链式调用的好处:

  • 代码简洁清晰: 可以在一行代码中完成多个对象状态的修改,使代码更加紧凑。
  • 可读性增强: 易于理解对象状态的设置顺序和逻辑。
  • 便于使用 fluent API: 在设计 fluent interface 时非常有用,提供一种流畅的接口风格。
  • Fluent Interface 是一种优雅的设计模式,通过返回对象自身的引用实现了链式调用,提升了代码的可读性和编写效率。它特别适合用于需要频繁进行多步设置的场景,能够简化代码结构,使其更具表达力和清晰度。

3.看看这一段代码

他可以正常打印输出吗?

    class A
    {
        int i;
        public:
        void Hello() 
        { 
            cout << "hello" << endl; 
        }
    };
    
    int main()
    {
        A * p = NULL;
        p->Hello(); //结果会怎样?
    }

答案是可以的,你可能会好奇,明明p是空指针,为什么还能正常打印呢?

实际上每个成员函数的第一个参数默认都有个指向对象的 this 指针,上述情况下如果该指向的对象是空,相当于成员函数的第一个参数是NULL,那么只要成员函数没有使用到成员变量,也是可以正常执行。

但倘若加上i ,就会报错啦。因为this指针是空的,使用了空的指针指向了成员变量i,程序就会奔溃。

3.要注意,静态成员函数不可以使用this指针,因为静态成员函数相当于是共享的变量,不属于摸个对象的变量,而this存储的是对象的地址,它指向的就是对象,所以静态成员函数它是没有this指针的。

说到这了,

2.什么是static,它的用法有哪些呢?

static是从C/C++中很常用的修饰符,它被用来控制变量的存储方式和可见性。

引入static:

我们知道在函数内部定义的变量,当程序执行到它的定义处时,编译器为它在栈上分配内存空间,函数在栈上分配的内存空间在此函数结束之后就会被释放掉,这样就产生了一个问题,如果想将函数中的变量保存值下一次调用时,改如何实现呢? 最容易想到的方法是定义一个全局的变量,但定义一个全局的变量有许多缺点,最明显的缺点就是破坏的次变量的访问范围,(使得此函数的变量不仅仅只受此函数的控制),static关键字则可以很好的解决这个问题。

另外,在C++中如果需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见时,可以将其定义为静态数据。

将成员变量和成员函数设置为static,他就不属于任何对象,而是属于这个类了,被类的实例所共享,成员变量分为

1.可见类内静态成员需要在类外进行初始化,(C++11标准之前),现在可以将静态成员在类内进行初始化,只不过需要加上const。

static的基本用法:

1、被 static 修饰的变量属于类变量,可以通过类名::变量名直接引用,而不需要 new 出一个类来

2、被 static 修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要 new 出一个类来而非静态成员不可以直接用类名直接调用。

使用static的几种情况总结:

  1. 修饰变量

  • 全局变量:

  • 链接属性由外部变成内部,即对其他文件不可见,只能在本文件使用。

  • 局部变量:

  • 作用域不变,生命周期变成整个程序的执行周期,在内存中的位置由栈区变为全局静态区。退出作用域,该变量不可访问,但是仍在内存中;如果再次进入作用域,则读取上次的结果继续使用。

  • 成员变量:

  • 必须在类外初始化(static成员变量先于类的对象存在,static程序启动时就在内存中,而对象需要等到执行到的时候才会在内存中),该变量在类的所有对象中共享,只存在一份。可以通过类名+作用域的形式访问。

  1. 修饰函数

  • 普通函数:

  • 链接属性由外部变成内部,即对其他文件不可见,只能在本文件使用。

  • 成员函数:

  • 该函数在类的所有对象中共享,只存在一份,可以通过类名+作用域形式访问。没有this指针,无法声明为虚函数、常函数,无法直接访问非静态成员变量(可通过对象的方式访问),无法调用非静态成员函数。如下图所示:

3.const的作用:

基本概念:

const允许我们指定一个语义约束,告诉编译器某个对象不应该被改变,而编译器会帮助我们实施这一项约束,如果我们认定某个值不能被改变,那么我们就应该使用const,来让编译器帮助我们来保证这个条件不会被违反。

适用场景:

const可以修饰很多内容,对于修饰变量,可以修饰局部的(必须立刻初始化,否则编译错误),全局的(默认初始化为0)或者成员变量(必须使用构造函数的初始化列表进行初始化),对于函数,可以修饰函数的返回值,函数的参数,对于指针,可以修饰指针本身,也可以修饰指针所指向的对象;对于类,可以修饰类的成员变量,也可以修饰类的成员函数。

举例说明:

比如我们重写一个操作符*,我们就应该把这个函数的返回值设置为const,因为我们知道这个操作符的返回值是不可以更改的,这样就可以避免一些错误的语法,比如a*b=c,(可能我们只是想判断a*b和c是否相等,但是误写成了=)。

标签:复习,--,函数,对象,static,Cpp,成员,变量,指针
From: https://blog.csdn.net/m0_62956971/article/details/141021748

相关文章

  • 构建即时通讯应用:Spring boot高效集成WebSocket、Stomp协议完成前后端持续通信
    1.引入依赖在你的SpringBoot项目的pom.xml中添加以下依赖:<dependencies><!--SpringBootStarterThymeleaf--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-st......
  • Spring依赖注入
    概念  依赖注入(DependencyInject,缩写DI)是由Ioc容器在运行期间动态地将某种依赖资源注入对象中。  基本思想:明确地定义组件接口,独立开发各个组件,然后根据组件的依赖关系组装运行。  DI数据类型:1、基本类型与String             2、......
  • Spring注解
          1、注入类                                 替换:<beanid=""class=""></bean>                  位置:类                 语法:@Component ......
  • SQL Zoo 7.More JOIN operations
    以下数据均来自SQLZoo1.Listthefilmswherethe yr is1962[Show id, title](列出1962年的电影)SELECTid,titleFROMmovieWHEREyr=19622.Giveyearof'CitizenKane'.(给出《公民凯恩》的年份)selectyrfrommoviewheretitle='CitizenKane'3.List......
  • 51单片机之模块化编程
    一、模块化编程与传统方式编程的区别传统方式编程:在这种编程方式中,所有的函数通常都被放置在同一个文件main.c中。当项目中使用的模块较多时,这个文件中会包含大量的代码,导致代码难以组织和管理,也影响了编程者的思路。这种方式缺乏清晰的结构划分,使得代码的可读性和可维护性降......
  • 河南萌新联赛2024第(四)场
    题目链接:河南萌新联赛2024第(四)场:河南理工大学_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ1.小雷的神奇电脑同或概念:•如果两个输入位相同,则输出为1•如果两个输入位不同,则输出为0 所以可以发现规律,最大同或一定出现在相邻两个数(二进制下位相同多),同时利......
  • Yum缓存包
    简单介绍 使用系统版本:[root@localhost~]#uname-aLinuxlocalhost5.14.0-427.13.1.el9_4.x86_64#1SMPPREEMPT_DYNAMICWedMay119:11:28UTC2024x86_64x86_64x86_64GNU/Linux[root@localhost~]#cat/etc/os-releaseNAME="RockyLinux"VERSION="9.......
  • 教你领悟函数递归的本质
    一、何为递归①在C语言中,递归就是函数自己调用自己。递是指递推,归是指回归。②递归的思想:将复杂的问题简单化。③递推的两个必要条件。a:递归存在限制条件,当满足限制条件时,递归便不再继续b:每一次递归都要越来越接近限制条件/*用递归的方式求n!(n>=0)*/intFact(i......
  • Java | Integer强转Double错误
    一、问题复现引发java.lang.ClassCastException:classjava.lang.Integercannotbecasttoclassjava.lang.Double错误的示例代码:publicclassClassCastExceptionExample{publicstaticvoidmain(String[]args){Objectnumber=Integer.valueOf(10);......
  • 利用StringBuffer把字符串反转
    packagecom.shujia.day11;importjava.util.Scanner;/*把字符串反转*/publicclassStringBufferDemo6{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);System.out.println("请输入一个要反转的字符串:");......