当前位置: 首页 > news >正文

[C++]——带你学习类和对象

类和对象——上

  • 目录:
  • 一、面向过程和面向对象
  • 二、类的概念
  • 三、类的访问限定符和封装
    • 3.1 访问限定符
    • 3.2 封装
  • 四、类的作用域
  • 五、类的实例化
  • 六、类的对象大小的计算
  • 七、类成员函数this指针
    • 7.1 this指针的引用
    • 7.2 this 指针的特性

目录:

类和对象是很重要的知识点,对于初学者也不容易理解。希望大家多学几遍,搞懂内容,在进一步学习下一步的内容,学习c++就得一步一步来,打好基础,稳定向前。

一、面向过程和面向对象

C语言是面向过程的,关注的是过程,分析求出解决问题的步骤,通过函数调用逐步解决问题。
c++是面向对象的,关注的是对象,将一件事情拆分为不同的对象,靠对象之间交互完成。

二、类的概念

1.类的引用

1.c++兼容c结构体的用法
2.c++把结构体升级成了类,类名就是类型(可以用class代替)。
3.类是一个整体,有成员变量和成员函数,并且位置任意。
4.struct默认公有,class默认私有。
5.类是一个整体,不需要定义在前面或者后面。

2.类的定义

class为定义类的关键字Classname为类的名字,{}中为类的主体注意类定义后面分号不能省略
类主体的内容称为类的成员:类中的变量叫成员变量,函数称为成员函数

类的两种定义方法:
1.声明和定义全部在类体中。

#include <iostream>
using namespace std;
class PerSon
{
public://公有得//成员函数:void person(){cout << "姓名:p" << endl;}
private://私有得// 成员变量:char* _name;//姓名char* _sex;//性别int _age;//年龄
};

2.类声明放在.h文件中,成员函数定义在cpp文件中,成员函数名前需要加类名::。
类声明和定义分离:
在这里插入图片描述
在这里插入图片描述
注意:
1.默认在类里面定义的函数,为内联函数(inline),这个由编译器决定是不是内联。
2.正确的用法;长的函数声明和定义分离,短小的函数可以直接在类里面定义(编译器决定内联函数)。

三、类的访问限定符和封装

c++实现封装的方式: 用类将对象的属性和方法结合在一块,让对象更加完善,通过访问限定符选择性的将接口提供给外部的用户使用。

3.1 访问限定符

在这里插入图片描述
[访问限定符说明]:

  1. public修饰的成员在类外可以直接被访问
  2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
  4. 如果后面没有访问限定符,作用域就到}即类结束。
  5. class的默认访问权限为private, struct为public(因为struct要兼容C)
    注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别
    [面试题]:
    问题: C++中struct和class的区别是什么?
    解答: C++需要兼容C语言,所以C++中struct可以当成结构体使用。另外C++中struct还可以用来定义类。和class定义类是一 样的,区别是struct定义的类默认访问权限是public, class定义的类默认访问权限是private。 注意:在继承和模板参数列表位置,struct和class也有区别。

3.2 封装

面向对象的三大特征:封装、继承、多态
封装本质上是一种管理,让用户更方便使用类。
**封装:**将数据和操作数据的方法进行有机结合,通过访问限定符隐藏对象的属性和实现细节,仅使用对外公开的接口来和对象进行交互。

四、类的作用域

**类定义了新的作用域,**类的所有成员都在作用域中。在类外定义成员时,需要用到::作用域操作符指明成员属于哪个类域。
在这里插入图片描述

五、类的实例化

用类类型创建对象的过程,称为类的实例化

  1. 类是对对象进行描述的,相当于一个模型成员变量是声明,限定了类有哪些成员,定义一个类并没有给它分配实际的内存空间来存储它。
    2.一个类可以实例化出多个对象,实例化出的对象,占用实际的物理空间,存储了类的成员变量。
    3.类只是一个设计,实例化出的对象才能存储数据,占用物理空间。
    在这里插入图片描述

分析如下:
在这里插入图片描述
在这里插入图片描述
总结:不同对象,成员函数调用的地址一样(数据不存对象里),成员变量存数据不一样(存在各自的对象里)

六、类的对象大小的计算

1.类对象的存储方式
类中既可以有成员变量,也可以有成员函数。(类里面只存成员变量,不存成员函数)
为什么成员变量在对象中,成员函数不在对象中?
一个类分为成员变量和成员函数,类的大小是由成员变量来决定得。这是因为每个对象的成员变量是不一样得,需要独立存储,而每个对象调用成员函数是一样的,都是放在共享公共区域(代码段)里。

2.类的大小计算
一个类的大小,实际上是该类“成员变量”之和,要注意内存对齐,要注意空类的大小,空类比较特殊,编译器给空类一个字节用来唯一标识这个类的对象(这个1byte不存储有效数据,是用来占位得,占位的意思是标识这个对象被实例化出来了)。

#include <iostream>
using namespace std;
//即有成员变量,又有成员函数
class A1
{
public:void f1(){};
private:int a;char b;short c;
};
//只有成员变量
class A2
{
private:int a;char b;short c;
};
//只有成员函数
class A3
{
public:void f1(){};
};
//没有成员函数,也没有成员变量
class A4
{//空
};
int main()
{cout << sizeof(A1) << endl;cout << sizeof(A2) << endl;cout << sizeof(A3) << endl;cout << sizeof(A4) << endl;return 0;
}

在这里插入图片描述
结构体的内存对齐规则

1.第一个成员在与结构体偏移量为0的地址处。
2.从第二个成员开始,成员变量要对齐到对齐数的整数倍的地址处。
注意:对齐数=编译器默认的一个对齐数与该成员大小的较小值,VS中默认对齐数为8.
3.结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4.嵌套结构体:嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

七、类成员函数this指针

this指针可以用来确定不同对象的成员函数,每个成员都有隐形的指针。

7.1 this指针的引用

在这里插入图片描述

C++中通过引入this指针解决了不同对象相同类调用成员函数(对象如何找到自己的成员函数)的问题:

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

7.2 this 指针的特性

1. this指针的类型:类的类型* const ,即成员函数中,不能给this指针赋值。
2. 只能在"成员函数”的内部使用。
3. this指针本质上是“成员函数”的形参 ,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
4. this指针是“成员函数"第一个隐含的指针形参, 一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。

扩展:

#include <iostream>
using namespace std;
class A
{
public://公有void Print(){cout << "Print()" << endl;}private://私有int _a;};
int main()
{A* s1=nullptr;s1->Print();return 0;
}

在这里插入图片描述

#include <iostream>
using namespace std;
class A
{
public://公有void Print(){cout <<this-> _a << endl;}
private://私有int _a;};
int main()
{A* s1 = nullptr;s1->Print();return 0;
}

在这里插入图片描述
仔细观察这两段代码,第一个正常运行,第二个运行崩溃。
1.this指针存在哪里?

this指针是个形参,是存在栈帧上面得,是隐含形参。(VS编译环境下,this指针存在函数栈帧中的寄存器里)

2.this指针可以为空吗?

在特定条件下可以为空, 成员函数地址不在对象里,成员变量在对象里,对象为空,只调用成员函数,且不需要用到隐含this指针时,就能正常运行。

补充:
c语言和c++的使用特点:

C语言:结构体中只能定义存放数据的结构,操作数据的方法不能放在结构体中,数据和操作数据的方法是分离开的,实现上相当复杂,涉及大量指针操作,很容易出错。
c++:c++通过类可以将数据以及操作数据的使用方法进行完美结合,通过权限访问可以控制这些方法在类外可以被调用,这就是封装。
c++中Stack* 参数是编译器维护,C语言中需要用户自己维护。
总结:

C语言:1.数据和方法是分离的。 2数据访问控制是自由的,不受限制。
c++:1.数据和方法都封装到类里面。2.控制访问方式。愿意给你访问就是公有,不愿意给你访问就是私有。
C语言和c++的底层都在代码段里,区别就是对数据的管理不同。

相关文章:

  • C++入门精讲——入门看完这一篇就够了
  • Go学习第十五章——Gin参数绑定bind与验证器
  • c:变参函数:汇编解析;va_list;marco 宏:__VA_ARGS__
  • 数字孪生与智慧城市:开启未来智慧生活
  • 2023CCF中国开源大会 | 麒麟信安作为首批合作伙伴入驻全国信创开源广场
  • 计算机专业毕业设计如何选题、如何规避风险、避免入坑
  • uniapp解决iOS切换语言——原生导航栏buttons文字不生效
  • Elasticsearch聚合----aggregations的简单使用
  • 软考系统架构师知识点集锦二:软件工程
  • Tensorflow2 中模型训练标签顺序和预测结果标签顺序不一致问题解决办法
  • jsp简单实现新闻发布系统中用户注册确认和用户模拟登录功能的开发
  • 设计模式之代理模式
  • 【RabbitMQ 实战】12 镜像队列
  • 跟我学C++中级篇——右值引用和万能引用
  • Positive Technologies 在迪拜宣布与地区网络安全解决方案提供商开展合作
  • [译]CSS 居中(Center)方法大合集
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • conda常用的命令
  • Cumulo 的 ClojureScript 模块已经成型
  • js对象的深浅拷贝
  • mysql innodb 索引使用指南
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Sublime Text 2/3 绑定Eclipse快捷键
  • ViewService——一种保证客户端与服务端同步的方法
  • vue2.0项目引入element-ui
  • Vue实战(四)登录/注册页的实现
  • Webpack 4x 之路 ( 四 )
  • webpack4 一点通
  • 坑!为什么View.startAnimation不起作用?
  • 目录与文件属性:编写ls
  • 判断客户端类型,Android,iOS,PC
  • 前嗅ForeSpider采集配置界面介绍
  • 入门级的git使用指北
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 1.Ext JS 建立web开发工程
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​iOS安全加固方法及实现
  • #{}和${}的区别是什么 -- java面试
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #微信小程序(布局、渲染层基础知识)
  • $.each()与$(selector).each()
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (原創) 物件導向與老子思想 (OO)
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .net 后台导出excel ,word
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .NET框架设计—常被忽视的C#设计技巧
  • @Data注解的作用
  • [C++进阶篇]STL中vector的使用