2.类和对象

目录

 1.类的引入

2.类的定义

3.类的访问限定符及封装

3.1访问限定符

​编辑

​编辑

 3.2封装

4类的作用域

5.类的实例化

6.类的对象大小的计算

6.1如何计算类对象的大小

6.2类对象的存储方式猜测

6.3 结构体内存对齐规则

 7.this指针

7.1this指针的引出

7.2this指针的特性


 1.类的引入

C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:

之前在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现,

会发现struct中也可以定义函数

#include<iostream>
using namespace std;
typedef int DataType;
struct Stack
{
    void Init(size_t capacity)
    {
        _array = (DataType*)malloc(sizeof(DataType) * capacity);
        if (nullptr == _array)
        {
            perror("malloc申请空间失败");
            return;
        }
        _capacity = capacity;
        _size = 0;
    }
    void Push(const DataType& data)
    {
        // 扩容
        _array[_size] = data;
        ++_size;
    }
    DataType Top()
    {
        return _array[_size - 1];
    }
    void Destroy()
    {
        if (_array)
        {
            free(_array);
            _array = nullptr;
            _capacity = 0;
            _size = 0;
        }
    }
    DataType* _array;
    size_t _capacity;
    size_t _size;
};
int main()
{
    Stack s;
    s.Init(10);
    s.Push(1);
    s.Push(2);
    s.Push(3);
    cout << s.Top() << endl;
    s.Destroy();
    return 0;
}

2.类的定义

class className
{
// 类体:由成员函数和成员变量组成
};  // 一定要注意后面的分号

class定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面

号不能省略

类体中内容称为类的成员:类中的变量称为类的属性成员变量; 类中的函数称为类的方法或者

成员函数

类的两种定义方式:

1. 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成

联函数处理。

class Person { //人
public:
	void showInfo()
	{
		cout << _name << "-" << _sex << _age << endl;
	}
public :
	char* _name;  //姓名
	char* _sex;	  //性别
	int _age;	  //年龄
};

2. 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::

成员变量命名规则建议:::::

class Date
{
public:
	void Init(int year)
	{
		_year = year;
	}
private:
	int _year;
};

或者这样也可以::::

class Date
{
public:
	void Init(int year)
	{
		mYear = year;
	}
private:
	int mYear;
};

3.类的访问限定符及封装

3.1访问限定符

C++ 通过 public、protected、private 三个关键字来控制成员变量和成员函数的访问权限(也称为可见性),分别表示:公有的、受保护的、私有的。所谓访问权限,就是能不能使用该类中的成员。
public:可以被该类中的函数、子类的函数、友元函数访问,也可以由该类的对象访问;

protected:可以被该类中的函数、子类的函数、友元函数访问,但不可以由该类的对象访问;

private:可以被该类中的函数、友元函数访问,但不可以由子类的函数、该类的对象、访问。

如果声明不写 public、protected、private,则默认为 private;

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

 我们先拿struct举例子

struct  test
{
	void PrintShow()
	{
		cout << _year<<" - " << _month << " - " << _day << endl;
	}
private:
	int _year = 1;
	int _month = 2;
	int _day = 3;
};
int main()
{
	test t1;
	t1.PrintShow();
	return 0;
}

 我们先拿class举例子

由此我们可以看出:struct定义的类默认访问权限是publicclass定义的类是private

 3.2封装

【面试题】
面向对象的三大特性: 封装、继承、多态
在类和对象阶段,主要是研究类的封装特性,那什么是封装呢?
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来
和对象进行交互。
封装本质上是一种管理,让用户更方便使用类 。比如:对于电脑这样一个复杂的设备,提供给用
户的就只有开关机键、通过键盘输入,显示器, USB 插孔等,让用户和计算机进行交互,完成日
常事务。但实际上电脑真正工作的却是 CPU 、显卡、内存等一些硬件元件。
对于计算机使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的, CPU 内部是如
何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此
算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以
及键盘插孔等,让用户可以与计算机进行交互即可
C++ 语言中实现封装,可以 通过类将数据以及操作数据的方法进行有机结合,通过访问权限来
隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用

4类的作用域

类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 ::作用域操作符指明成员属于哪个类域。

5.类的实例化

用类类型创建对象的过程,称为类的实例化
1. 类是对对象进行描述的 ,是一个 模型 一样的东西,限定了类有哪些成员,定义出一个类 并没
有分配实际的内存空间 来存储它;比如:入学时填写的学生信息表,表格就可以看成是一个
类,来描述具体学生信息。
类就像谜语一样,对谜底来进行描述,谜底就是谜语的一个实例。
谜语: " 年纪不大,胡子一把,主人来了,就喊妈妈 " 谜底:山羊
2. 一个类可以实例化出多个对象, 实例化出的对象 占用实际的物理空间,存储类成员变量
Person 类是没有空间的,只有 Person 类实例化出的对象才有具体的年龄。
3. 做个比方。 类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图 ,只设
计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象
才能实际存储数据,占用物理空间
class Person
{
public:
	void showInfo();
public:
	char* _name[20];
	char* _gender[20];
	int _age;
};
int main()
{
	Person man;
	man.showInfo();
	man._age;
	man._gender;
	man._name;
	return 0;
}

6.类的对象大小的计算

6.1如何计算类对象的大小

class A {
public:
	void Print()
	{
		cout << _a << endl;
	}
private:
	char _a;
};
int main()
{
	cout << sizeof(A) << endl;
	return 0;
}
问题:类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?如何计算 一个类的大小?

 

6.2类对象的存储方式猜测

C语言中结构体的对齐-》-》-》-》-》

我们介于一下三种猜想!!

  • 对象中包含类的成员变量

  • 代码只保存一份,在对象中保存存放代码的地址

  • 只保存成员变量,成员函数存放在公共的代码段

结论:一个类的大小,实际就是该类中 成员变量 之和,当然要注意内存对齐
注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。

6.3 结构体内存对齐规则

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

 7.this指针

7.1this指针的引出

class Date {
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1,d2;
	d1.Init(2008, 12, 12);
	d2.Init(2000, 11, 11);
	d1.Print();
	d2.Print();
	return 0;
}
对于上述类,有这样的一个问题:
Date 类中有 Init Print 两个成员函数,函数体中没有关于不同对象的区分,那当 d1 调用 Init
数时,该函数是如何知道应该设置 d1 对象,而不是设置 d2 对象呢?
C++ 中通过引入 this 指针解决该问题,即: C++ 编译器给每个 非静态的成员函数 增加了一个隐藏
的指针参数,让该指针指向当前对象 ( 函数运行时调用该函数的对象 ) ,在函数体中所有 成员变量
的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编 译器自动完成

7.2this指针的特性

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

编译器处理成员函数隐藏this指针

void Display()
{
	cout<<_year<<endl;
}
// 底层
void Display(Date* this)
{
	cout<<this->_year<<endl;
}

面试题
1.this指针存在哪里?
        其实编译器在生成程序时加入了获取对象首地址的相关代码。并把获取的首地址存放在了寄存器ECX中(VC++编译器是放在ECX中,其它编译器有可能不同)。也就是成员函数的其它参数正常都是存放在栈中。而this指针参数则是存放在寄存器中。类的静态成员函数因为没有this指针这个参数,所以类的静态成员函数也就无法调用类的非静态成员变量。

2.this指针可以为空吗?
        可以为空。当我们在调用函数的时候,如果函数内部不需要通过this指向当前对象并对其进行操作时才可以为空(当我们在其中什么都不放或者在里面随便打印一个字符串);如果调用的函数需要指向当前对象,并进行操作,则会发生错误(空指针引用)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/548695.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp h5项目上传图片到oss(纯前端)

需求&#xff1a;后端给前端一个oss上传地址&#xff0c;前端需要根据getCkOSSToken获取stsToken,使用client.put方法将图片上传成功&#xff0c;并且使用canvas压缩图片 效果图 废话不多说&#xff0c;直接上代码&#xff0c;代码可直接复制&#xff0c;运行 准备工作 cnpm…

Pytorch(GPU版本)简介、安装与测试运行

目录 Pytorch简介Pytorch安装查看CUDA版本Pytorch命令安装Pytorch测试运行Pytorch简介 PyTorch是一个开源的Python机器学习库,基于Torch,用于自然语言处理等应用程序。PyTorch既可以看作加入了GPU支持的numpy,同时也可以看成一个拥有自动求导功能的强大的深度神经网络。 2…

中医圆运动规律

目录 人体圆运动营气在十二经脉的运行规律子午流注与圆运动升降结合图 人体圆运动 营气在十二经脉的运行规律 营气在脉中&#xff0c;卫气在脉外 这个顺序也是子午流注的顺序 子午流注与圆运动升降结合图

火绒安全的详细用法

1. 引言 本章将介绍火绒安全软件的基本概述和用法。火绒安全是一款功能强大的安全软件,提供了多种保护功能和工具,可以帮助您保护计算机免受恶意软件、网络攻击和其他安全威胁的侵害。 2. 火绒安全的功能 火绒安全具有以下主要功能: 实时防护:火绒安全提供实时监测和防护…

为硬刚小米SU7,华为智界S7整出了「梅开二度」操作

如今国产中大型新能源轿车市场&#xff0c;在小米 SU7 加入后&#xff0c;可算彻底活了过来。 过去几年&#xff0c;咱们自主新能源品牌在 20-30 万元级轿车上发力明显不足&#xff0c;老牌车厂比亚迪汉几乎以一己之力扛起销量担当。 随着新能源汽车消费升级、竞争加剧&#x…

基于SSM的购物小程序01

4.1系统架构设计 购物系统设计的系统项目的概述设计分析&#xff0c;主要内容有学习平台的具体分析&#xff0c;进行数据库的是设计&#xff0c;数据采用mysql数据库&#xff0c;并且对于系统的设计采用比较人性化的操作设计&#xff0c;对于系统出现的错误信息可以及时做出处…

WordPress 多站点切换域名完整指南:详细步骤和注意事项

因为公司的需要&#xff0c;需要对 WordPress 多站点进行域名切换, 一开始我也找了相关的方案和教程&#xff0c;但是很可惜&#xff0c;国内这一块网上的资料几乎为0&#xff0c;所以我把实现的过程写了一篇文章分享出来&#xff0c;为后来的人铺路。 开始之前&#xff0c;先…

红黑树(Red Black Tree)

红黑树&#xff08;Red Black Tree&#xff09; 红黑树&#xff08;Red Black Tree&#xff09; 是一种自平衡二叉查找树 红黑树是在1972年由Rudolf Bayer发明的&#xff0c;当时被称为平衡二叉B树&#xff08;symmetric binary B-trees&#xff09;后来&#xff0c;在1978年…

文件上传App,H5,小程序多端兼容

插件地址&#xff1a;https://ext.dcloud.net.cn/plugin?id5459 下载lsj-upload插件 代码如下 结构 <lsj-upload :option"option" :size"size" :formats"formats" :debug"debug":instantly"instantly" change"…

Element-Ui的Form表单:Label文本两端对齐,且必填项的*不影响布局

1. HTML 结构 首先&#xff0c;确保你的 HTML 或 Vue 模板中有一个 el-form 组件&#xff0c;类似下面这样&#xff1a; <div id"app"><el-form :model"form" label-width"100px"><el-form-item label"用户名">&l…

平台工程在企业数字化转型中的战略价值

要建设成功、有弹性和面向未来的平台&#xff0c;需要做到这三点&#xff1a;了解需求、预测可能面临的挑战并制定经得起时间考验的解决方案。 了解需求是指理解利益相关者的要求和目标&#xff0c;无论他们是最终用户、开发人员还是平台生态系统中的其他相关方。这包括开展全面…

HTTPS 加密解密大致流程

HTTPS简介 在我们开始配置之前&#xff0c;让我们先了解一下HTTPS和它的重要性。 为什么选择HTTPS&#xff1f; 加密传输&#xff1a;通过SSL/TLS协议&#xff0c;确保数据在传输过程中不被窃听。认证身份&#xff1a;确保客户端与预期的服务器通信&#xff0c;防止中间人攻…

梵宁教育:全面解析设计课程,助力职场新人技能飞跃

在数字化浪潮席卷全球的今天&#xff0c;设计行业以其独特的魅力和无穷的创新力&#xff0c;成为职场新人竞相追逐的热门领域。梵宁教育&#xff0c;作为一家专注于设计教育的机构&#xff0c;以其全面而深入的设计课程&#xff0c;为职场新人提供了技能飞跃的有力支持。 梵宁…

vue3 el-table无表头

需要实现的样式 父组件 <template><div><!-- 表格组件 无表头 --><Table :label"tableData.label" :data"tableData.data" :querydata"tableData.querydata" :queryTitle"tableData.title"><template #o…

企业网站建设需要了解什么

在现代商业环境中&#xff0c;企业网站已经成为企业宣传、推广和销售的重要工具。企业网站的建设需要考虑多个因素&#xff0c;包括以下几个方面&#xff1a; 首先&#xff0c;了解企业的目标和定位。企业网站的建设应该围绕企业的目标和定位展开&#xff0c;以达到企业在市场中…

低代码开发平台权威推荐:创新开发、领跑市场!

Gartner是低代码领域的一家权威机构&#xff0c;该机构常常通过"魔力象限"的研究方法&#xff0c;评选全球范围内IT细分领域的产品&#xff0c;来帮助决策者提供重要的咨询建议。本文盘点了Gartner机构推荐的6款低代码平台&#xff1a;Zoho Creator、Mendix、Oracle、…

新零售门店、商品、会员管理指标体系总览

新零售&#xff0c;旨在打破传统零售业的边界&#xff0c;引入先进科技和数字化手段&#xff0c;通过整合线上线下渠道&#xff0c;全面提升用户体验&#xff0c;并实现更智能、高效、个性化的零售运营模式。这一模式不仅仅关注销售产品&#xff0c;更注重构建全方位的购物生态…

(BERT蒸馏)TinyBERT: Distilling BERT for Natural Language Understanding

文章链接&#xff1a;https://arxiv.org/abs/1909.10351 背景 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;预训练语言模型&#xff08;如BERT&#xff09;通过大规模的数据训练&#xff0c;已在多种NLP任务中取得了卓越的性能。尽管BERT模型在语言理解和生成…

【刷题笔记】第一天

两道贪心题 文章目录 [3106. 满足距离约束且字典序最小的字符串](https://leetcode.cn/problems/lexicographically-smallest-string-after-operations-with-constraint/)[3107. 使数组中位数等于 K 的最少操作数](https://leetcode.cn/problems/minimum-operations-to-make-me…

ubuntu安装python3.10

1. 官网下载源程序 2. 解压进入文件夹&#xff1a; ./configure --prefix/usr/local/python3/ 3. 编译安装&#xff1a; make && make install 4. 添加环境变量&#xff1a; vim ~/.bashrc PATH/usr/local/python3/bin:$PATH #保存后&#xff0c;刷新配置文件 sour…