【C++】类和对象(上)

简介: 【C++】类和对象(上)

下面是对“类和对象相关知识的总结",有需要借鉴即可。

1.面向过程与面向对象的初步认识

C语言是面向过程的语言,需要关注事物的发展过程,往往比较繁杂。

C++是面向对象且兼容面向过程的语言,侧重于关注不同对象,使用起来更加便捷。

既然C++面向对象可以提供许多便捷,那CPP也引入了相应的具体语法:

2.类

一个面向过程的语言往往思考比较困难,因而CPP引入了”类“的概念

为了支持类语法,CPP分别进行了语法升级和引入新语法

  • 一方面CPP对struct进行了升级
  • 1.cpp中的struct可以兼容C的结构体语法
  • 2.cpp中的struct可以包含类的成员变量、成员函数
  • 另一方面也单独引入了一个新的语法,类。

2.1类的概念

类是对对象描述的一种未填属性的模板,没有实际的内存空间

2.2类的声明

2.2.1概念:

CPP规定,类语法有两种声明形式:struct/class

2.2.2语法:

两种声明形式的区别:

  • 1.struct兼容C的结构体语法,class是一种CPP专有新语法
  • 2.默认情况下,struct成员变量/函数为公开状态,class成员变量/函数为私有状态。

建议:类成员的命名规则:


我们一般建议成员变量名称前置下划线

为什么要建议实行这种类的命名规则?

为了避免成员变量名称与成员函数参数名称的混淆

  但是,类的声明仅仅是告诉编译器有这么一个“模板”,想要使用类,不光要有类的声明,还得需要类的定义以及类的访问。

2.3类的定义(类实例化)

前面提到过,类只不过是一种空白的模板而已,并不在内存中实际存在,因而要想使用类,首先要实例化出一个实际存在的类来,我们把这个过程称为“类的对象实例化”,把这个具体的实例化事物称之为“类对象”。

2.3.1概念:

按照类这个“模板”在内存中实际开辟空间,通常我们称之为“类的实例化”。

eg:Date d1;

2.4类的访问

2.4.1概念:通过类的实例化,对类对象进行访问。

在具体往下说的话,我们需要谈到“封装”这种管理方式了。

2.4.2封装:

封装概念:

将类中的成员变量/函数通过针对性的对外隐藏所实现的一种隐藏细节的管理方式。

CPP中为了实现对类的封装管理,引入了新的语法:访问限定符

访问限定符:

那封装的意义何在呢?

封装的意义:

能够有效规范化程序,可以有效降低程序规范性对程序员个人素质的依赖。

2.4.3类的访问格式:

类对象 + 点 + 成员变量/函数

3.类对象的存储原理

类对象到底在内存中怎么进行存储的呢?这就来到了类对象的“存储模型”了。

3.1类对象模型

对于成员变量,单独存放在栈帧中,而成员函数为了节省空间的考量,而放到了公共代码区所有类对象共享。

通过上面的类对象模型我们知道,类对象中成员变量是分开存储的,而类对象中的函数是共用一份的,那么其大小改如何进行计算呢?---->类对象的大小由类成员变量决定。

3.2类对象大小的计算

3.2.1计算规则:

类成员大小的计算遵循下面两条规则

  • 只计算类对象中成员变量的大小
  • 遵循内存对齐原则

3.2.2计算示例:

思考:内存对齐会浪费空间,那为什么还要进行内存对齐呢?

主要是为了效率的考量

  • 1.硬件规定,每次cpu读取的大小为4/8字节
  • 2.且需要从内存整数倍开始读

内存对齐是一种以空间换时间的行为,主要是为了效率的考量。

  我们上面了解到,成员变量是存储在内存栈中的,而成员函数为了节省内存空间的考量是放在公共代码区的,那成员函数是怎么拿到成员变量的呢?

其实,为了解决成员函数拿到类对象中的值的问题,成员函数中隐藏了特殊的指针,this指针,指向整个类对象。

4.类成员函数中隐藏的this指针

4.1this指针的隐藏性

从代码表面上看,并没有所谓的this指针,但是实际上是有的,如下图:

那类成员函数是如何通过this指针来拿到类成员变量中的值的呢?

下面是类成员函数逻辑访问图:

4.2this指针的特性

  • 1.我们不能把this指针写出来,这工作属于编译器。
  • 2.this指针可以在成员函数内部使用。
  • 3.this指针指向不可更改

思考:this指针存放在哪个存储区?

堆/栈/对象内/静态区/常量区???

this指针式作为函数第一个形参来存放在函数栈帧中的。

4.3对类对象存储原理的理解

  • 1.类对象的成员变量是存放在类对象地址指向的区域的,因而需要有效的地址。

  • 2.类对象的成员函数是存放在公共代码区的,调用此函数不需要类对象地址。

5.练习题:


EOF

相关文章
|
5天前
|
C++
C++(十一)对象数组
本文介绍了C++中对象数组的使用方法及其注意事项。通过示例展示了如何定义和初始化对象数组,并解释了栈对象数组与堆对象数组在初始化时的区别。重点强调了构造器设计时应考虑无参构造器的重要性,以及在需要进一步初始化的情况下采用二段式初始化策略的应用场景。
|
5天前
|
存储 编译器 C++
C ++初阶:类和对象(中)
C ++初阶:类和对象(中)
|
5天前
|
C++
C++(十六)类之间转化
在C++中,类之间的转换可以通过转换构造函数和操作符函数实现。转换构造函数是一种单参数构造函数,用于将其他类型转换为本类类型。为了防止不必要的隐式转换,可以使用`explicit`关键字来禁止这种自动转换。此外,还可以通过定义`operator`函数来进行类型转换,该函数无参数且无返回值。下面展示了如何使用这两种方式实现自定义类型的相互转换,并通过示例代码说明了`explicit`关键字的作用。
|
5天前
|
存储 设计模式 编译器
C++(十三) 类的扩展
本文详细介绍了C++中类的各种扩展特性,包括类成员存储、`sizeof`操作符的应用、类成员函数的存储方式及其背后的`this`指针机制。此外,还探讨了`const`修饰符在成员变量和函数中的作用,以及如何通过`static`关键字实现类中的资源共享。文章还介绍了单例模式的设计思路,并讨论了指向类成员(数据成员和函数成员)的指针的使用方法。最后,还讲解了指向静态成员的指针的相关概念和应用示例。通过这些内容,帮助读者更好地理解和掌握C++面向对象编程的核心概念和技术细节。
|
18天前
|
存储 算法 编译器
c++--类(上)
c++--类(上)
|
25天前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
|
25天前
|
编译器 C++
virtual类的使用方法问题之静态和非静态函数成员在C++对象模型中存放如何解决
virtual类的使用方法问题之静态和非静态函数成员在C++对象模型中存放如何解决
|
25天前
|
编译器 C++
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
|
5天前
|
存储 C++
C++(五)String 字符串类
本文档详细介绍了C++中的`string`类,包括定义、初始化、字符串比较及数值与字符串之间的转换方法。`string`类简化了字符串处理,提供了丰富的功能如字符串查找、比较、拼接和替换等。文档通过示例代码展示了如何使用这些功能,并介绍了如何将数值转换为字符串以及反之亦然的方法。此外,还展示了如何使用`string`数组存储和遍历多个字符串。
|
14天前
|
存储 C++
C++ dll 传 string 类 问题
C++ dll 传 string 类 问题
15 0