lesson1-C++类和对象(上)

news2024/10/7 9:17:05

个人主页:Lei宝啊 

愿所有美好如期而遇


目录

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

2.类的引入

3.类的定义

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

5.类的作用域

6.类的实例化

7.类的对象大小的计算

8.类成员函数的this指针


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

在C语言中,除了库中的函数,你会发现我们想实现些什么都要自己写,而且还有很多不方便的地方,这样那样的缺陷和不足,相信很多人都比较难受,我们C++的祖师爷他也难受,所以才开创了C++。

C语言就是一门面向过程的语言,什么叫面向过程,就是注重过程,好比洗衣服,整个流程自己弄,相当于让你写篇小作文,详细写你是如何洗衣服的。而面向对象,就是你妈妈让你洗衣服,问你洗完衣服了吗,你说我用洗衣机洗完了。

总结:

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

2.类的引入

C 语言结构体中只能定义变量,在 C++ 中,结构体内不仅可以定义变量,也可以定义函数。 比如:
之前在数据结构初阶中,用 C 语言方式实现的栈,结构体中只能定义变量 ;现在以 C++ 方式实现,
会发现 struct 中也可以定义函数
#include <iostream>
using namespace std;

struct S
{
	int a = 1;
	int top = 0;

	int Add(int x, int y)
	{
		return a + x + y;
	}
};

int main()
{

	S a;
	cout << a.Add(1, 2) << endl;

	return  0;
}

当然,C++中类更喜欢用class来表示,而且class与struct有一点区别在于struct默认域里的成员函数和成员变量公有,而class默认私有,这个后面会说。 

3.类的定义

class className
{
// 类体:由成员函数和成员变量组成
};   // 一定要注意后面的分号
类体中内容称为 类的成员: 类中的 变量 称为 类的属性 成员变量 ; 类中的 函数 称为 类的方法 或者
成员函数
类的两种定义方式:
1. 声明和定义全部放在类体中,需注意:成员函数如果 在类中定义 ,编译器可能会将其当成 联函数 处理。
class person
{

public:
	void COUT(int a)
	{
		_a = a;
		cout << "这是个人" << endl;
	}

private:
	int _a;
	int _b;
	int _c;
};

我们需要理解的一点是,类是一个整体,我们_a的声明虽然在后面,但是COUT函数在函数里找不到_a的时候,会在整个类里去找,这是编译器的一种搜索规则,namespace同理。

也就是说,在类里,同时支持向上和向下搜索,而C语言只支持向上。

pubilc和private一会儿会提到,莫急,往下看。

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

一般来说,函数体内的代码超过20行,编译器就不会采纳你的建议,将他当成内联函数了,所以我们下面的函数,100行代码的函数也写在类里的话,对于我们查看类里的内容,比如说各种声明时就不方便,而且编译器也不会将他当成内联函数,吃力不讨好,就可以考虑写在外面。

class person
{

private:
	int _a;
	int _b;
	int _c;

public:
	void COUT()
	{
		cout << "哈哈" << endl;
	}
	
	void crush()
	{
		//...假设这里有100行代码
	}

};

int main()
{

	person a;
	for (int i = 0; i < 100; i++)
	{
		a.crush();
	}

	return 0;
}

写在外面:

class person
{

	//即使我们不写private,class里也会默认他是private
	//但最好写上,可读性会好些
private:
	int _a;
	int _b;
	int _c;

public:
	void COUT()
	{
		cout << "哈哈" << endl;
	}
		
	//假设这个函数有100行代码
	void crush();
};

void person::crush()
{
	//100行代码...
}

COUT函数可以写在里面 ,因为他函数体里代码并不多,也适合作为内联函数,内联函数不适合递归,适合代码量少但又频繁使用的情景。

成员变量命名规则的建议
class date
{

public:
    //这里的year到底是哪个year呢》成员变量还是参数??
	void Init(int year, int month, int day)
	{
		year = year;
		month = month;
		day = day;
	}

	int year;
	int month;
	int day;

};

int main()
{

	date a;

	a.Init(1, 2, 3);
	cout << a.year << a.month << a.day << endl;

	return 0;
}

并没有初始化a对象里的year,month和day。

 

所以我们需要标识类里的成员变量。

class date
{

public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	int _year;
	int _month;
	int _day;

};

int main()
{

	date a;

	a.Init(1, 2, 3);
	cout << a._year << a._month << a._day << endl;

	return 0;
}

 C++里习惯给成员变量名字前或者后加上下划线标识,这不是标准,也不是规定,只是一种习惯,当然也有人会这样mYear,都可以,看你在哪家公司了。

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

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

访问限定符:

public:(公有)

protect:(保护)

private:(私有)

现阶段我们可以将保护等同于private,区别在继承那个知识点会说到。现在我们用private就可以。

【访问限定符说明】
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也有区别,后序给大
家介绍
封装:
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来 和对象进行交互。

也就是说可以使用类里公开的方法实现你想实现的,但是如何实现你不知道,也无法直接修改和查看类里私有的成员变量。

好比一个计算机,你可以使用计算机算数,但是他如何实现,以及工作原理你是不清楚的,这就是封装。

5.类的作用域

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

就如同我们上面将类里较长的方法写在外面一样,需要::指明 。

6.类的实例化

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

我们先看一个例子:

class S
{

public:
	int getNum_a()
	{
		return _a;
	}

	int setNum_a(int a)
	{
		_a = a;
	}

private:
	int _a;
	int _b;

};
int main()
{

	//可以这样使用吗?
	S.getNum_a();

	return 0;
}

答案是不可以的。

如果这样使,那么一个类岂不是只能使用一次?再想用还得再写一个类?

1. 类是对对象进行描述的 ,是一个 模型 一样的东西,限定了类有哪些成员,定义出一个类 并没 有分配实际的内存空间 来存储它

也就是说,我们仅仅类进行了声明,就像我们C语言里使用的函数,我们有声明,有定义,但是在不调用这个函数时,编译器不会为他开辟栈帧,也就是空间,我们的类在没有实例化出对象时编译器也是不会分配空间给类的。

int main()
{

	S a;

	a.setNum_a(6);
	cout << a.getNum_a() << endl;

	return 0;
}

所以这样实例化对象,我们的对象就是a,类型为S这个类,所以我们的a就有了空间大小,可以调用a里的各种方法。

 2. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量

int main()
{

	S a;
	S b;
	S c;

	return 0;
}

这样是可以的。

但是由此我们也引出了一个问题,那就是每一个对象里的方法都要开空间吗,这显然不是,就像一个小区,人就是对象,篮球场就是方法,房间就是成员变量,房间不可以共享,但是篮球场是可以的,而且用的是同一个篮球场。

也就是说,有一个公共区来存放我们类里的方法,方法并不在对象里存储,我们可以验证一下。

这就是事实,只计算了private里的成员变量,大小为8个字节,计算规则与C语言里计算结构体大小的方法是一样的,可以参考:自定义类型详解。

7.类的对象大小的计算

 参考:自定义类型详解

但是有一点不同的是空类的大小。

测试空类大小
#include <iostream>
using namespace std;

class mid
{

public :
	void COUT()
	{
		cout << "cout" << endl;
	}

private:
	int a;
	int b;
	int c;

};

class null
{

};

int main()
{

	mid a;
	cout << sizeof(a) << endl;

	null b;
	cout << sizeof(b) << endl;

	return 0;

 

空类实例化出的对象大小不为0。

8.类成员函数的this指针

#include <iostream>
using namespace std;

class Stack
{

public :

	void push(int x)
	{
		cout << "push:x" << endl;
	}

	void pop()
	{
		cout << "pop" << endl;
	}

	//构造函数和析构函数要公有
	Stack()
	{
		int _capacity = 3;
		int* _a = (int*)malloc(sizeof(int) * _capacity);
	}

	//这里有一个隐含的指针Stack *this
	//但是在实参和形参处不可以显式写出来,函数里可以。
	Stack(int capacity)
	{
		//_capacity = capacity;
		// int* _a = (int*)malloc(sizeof(int) * _capacity);
		
		//在这里实际上是这样的
		this->_capacity = capacity;
		int* a = (int*)malloc(sizeof(int) * this->_capacity);	
	}

	~Stack()
	{
		free(_a);
		_top = 0;
		_capacity = 0;
	}

private:
	int* _a;
	int _top = 0;
	int _capacity;

};

int main()
{

	Stack c;

	//这里编译器会替我们做处理
	//隐含地传了&c,不可显式写出。
	c.push(1);
	c.pop();

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 框架学习 Django篇 (五) Session与Token认证

我们前面经过数据库的学习已经基本了解了怎么接受前端发过来的请求&#xff0c;并处理后返回数据实现了一个基本的登录登出效果&#xff0c;但是存在一个问题&#xff0c;我们是将所有的请求都直接处理了&#xff0c;并没有去检查是否为已经登录的管理员发送的&#xff0c;如果…

基于ssm网上鲜花店

功能如下图所示 摘要 基于SSM&#xff08;Spring、Spring MVC、MyBatis&#xff09;的网上鲜花店&#xff0c;是一款全面电子商务平台&#xff0c;为用户提供了多层次、多功能的鲜花购物体验。该系统的架构结构使得用户可以注册、浏览商品、购物车管理、下单和支付等一系列操作…

智慧园区内涝积水解决方案

在当今园区化快速发展的背景下&#xff0c;智慧园区已经成为园区可持续发展的重要组成部分。然而&#xff0c;智慧园区的规划和运营需要一个综合性的方法&#xff0c;以应对各种挑战&#xff0c;其中之一是积水管理。为了有效地解决这一问题&#xff0c;WITBEE万宾针对智慧园区…

Linux 僵尸进程处理

现象 查看: # 查看僵尸进程 ps -aux |grep Z## ps -aux |grep Z|wc -l 定位僵尸进程 ## ps -A -ostat,ppid,pid,cmd |grep -e ^[Zz] 杀死僵尸进程 使用Kill -HUP 僵尸进程ID来杀死僵尸进程,往往此种情况无法杀死僵尸进程,此时就需要杀死僵尸进程的父进程。 kill -HUP …

051校园短期闲置资源置换平台

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…

【异步爬虫】requests和aiohttp中代理IP的使用

前言 在进行爬虫开发时&#xff0c;我们常常需要使用代理IP来隐藏自己的真实IP地址&#xff0c;以避免被一些网站限制或封禁。requests和aiohttp是两个非常常用的工具&#xff0c;本文将分别介绍如何在它们中使用代理IP&#xff0c;希望可以帮助大家更好地进行异步爬虫开发。 …

1024程序员节特辑 | 解密Spring Cloud Hystrix熔断提高系统的可用性和容错能力

目录 1、Spring Cloud Hystrix 的背景和意义2、Spring Cloud Hystrix 的架构设计3、Spring Cloud Hystrix 的主要组件4、Spring Cloud Hystrix 熔断器的底层原理和整体架构5、Spring Cloud Hystrix 命令6、Spring Cloud Hystrix 熔断器7、Spring Cloud Hystrix参数说明8、Sprin…

点云平面拟合新国标怎么应对?

文章目录 一、应用背景二、算法原理三、代码实现首先我们看一下平面度的概念: 平面度:测量点集合中,在平面上方且距离基准平面最远的点到平面的距离+在平面下方且距离基准平面最远的点到平面的距离。 一、应用背景 在旧标准中,使用最小二乘法去拟合全部点,以拟合平面作为…

Cesium 实战 - 调整饱和度、对比度等参数,加载渲染美化影像底图

Cesium 实战 - 调整饱和度、对比度等参数&#xff0c;加载渲染美化影像底图 渲染美化影像底图核心代码完整代码&#xff1a;在线示例 本文包括渲染美化影像底图核心代码、完整代码以及在线示例。 渲染美化影像底图核心代码 这里放上核心代码&#xff1a; /*** todo 开启美化底…

阿里云oss丨You have no right to access this object because of bucket acl.

错误&#xff1a;You have no right to access this object because of bucket acl. ​ ​ 今天折腾oss的时候遇到这个问题&#xff0c;我以为是我没加白名单&#xff0c;后来想了下应该是使用阿里云OSS上传文件服务时报的错&#xff0c;新建的子用户AccessKey没有配置相应的管…

2023年最佳项目管理软件排行榜揭晓!

根据网络数据调查结果显示&#xff0c;今年有77%的组织将效率列为优先事项&#xff0c;而82%的领导人确认投资于新的项目管理和工作管理方案以提高效能。然而随着对价值的重新关注&#xff0c;选择适合的工程项目管理软件变得比以往任何时候都更加重要。好消息是通过对39个主要…

拿下域控主机

1.装域控环境 是dns环境 域控dns127.0.0.1 二.搭建 加入域 新建域用户 密码和域内主机一样 添加账户和密码 添加到域管理 这个随便 为了后期实验添加上 添加web和远程桌面 域控 用户添加到域 配置dns 攻击 kali 是公网 配置 木马服务器 哈希值 win10 客…

协同过滤推荐算法UserCF、ItemCF

目录 相似度计算基于用户的协同过滤&#xff08;UserCF&#xff09;算法评估基于物品的协同过滤&#xff08;ItemCF&#xff09;协同过滤算法的权重改进协同过滤算法的问题分析思考学习参考 相似度计算 杰卡德&#xff08;Jaccard&#xff09;相似系数 Jaccard 系数是衡量两个…

AMD推出锐龙Threadripper 7000处理器 96核重回HEDT市场

AMD今天正式推出了锐龙Threadripper 7000系列处理器&#xff0c;而且这次不光只有面向工作站的锐龙Threadripper PRO 7000WX系列&#xff0c;还有面向HEDT平台的锐龙Threadripper 7000X系列。 上一代的锐龙Threadripper PRO 5000是去年年初推出的&#xff0c;相隔已经有一年半…

一次说全COLA应用架构

一&#xff0c;为什么需要好的应用架构 上图比较清晰地说明了好的应用架构的作用——去繁为简&#xff0c;化无序为有序。 二&#xff0c;关于COLA的几种定义 1&#xff0c;原版 GitHub - alibaba/COLA: &#x1f964; COLA: Clean Object-oriented & Layered Architec…

【Linux】文件IO基础知识——上篇,文件描述符是什么??系统缓冲区又是啥??

目录 前文 一&#xff0c; 系统级——文件操作接口 a. open b. close c. write d. read 二&#xff0c;接口理解 那文件描述符——fd是什么呢&#xff1f; 三&#xff0c;文件描述符分配规则 原理 四&#xff0c;重定向——dup2 简易shell——重定向 五&#xff0c…

vue3+ts 使用vue-print-nb 打印功能【完美】

安装 npm i vue3-print-nb -s我的版本 0.1.4 注册 import { createApp } from vue import pinia from ./store import router from ./router import ./assets/css/main.scss import { globalRegister } from /global/register import ant-design-vue/es/message/style/css …

织造业的数字安全守护者:深入了解迅软DSE数据加密

客户简要介绍 某织造企业成立于2004年&#xff0c;工厂位于苏州平望&#xff0c;公司目前拥有先进纺织设备330台套和日本瑞士等前道配套设备&#xff0c;公司占地33亩、具有现代化标准厂房办公楼等3万平米。 某织造企业面料、功能性面料、新材料面料的生产商&#xff0c;公司坚…

UE5 ChaosVehicles载具 实现大漂移 (连载四)

载具设置成前驱模式 前轮摩擦力倍增x5 后轮摩擦力倍增x0.5

Linux 基础操作手记三(内存篇)

Linux 基础操作手记三 释放内存虚拟机彻底无网络测试网速设置虚拟内存交换空间未使用虚拟机设置虚拟内存无法开机问题GParted - 分配内存系统盘扩容自己 释放内存 sync && echo 3 > /proc/sys/vm/drop_caches 虚拟机彻底无网络 还原默认设置&#xff0c;静静的等待…