类和对象(1)

news2024/7/6 18:50:52

文章目录

  • 1.面向过程和面向对象初步认识
  • 2.类的引入
  • 3.类的定义
  • 4.类的访问限定符和封装
    • 4.1访问限定符
    • 4.2封装
  • 5.类的作用域
  • 6.类的实例化
    • 6.2结构体内存对齐规则
  • 7.this指针
    • 7.2this指针的特性
  • 封装(补充)

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

C++面向对象但不纯面向对象。JAVA纯面向对象。
所以C++支持C和C++面向对象混编。
C面向过程,关注的是过程

2.类的引入

类和结构体的区别:

  1. 类里可以有数据:成员变量
  2. 类可以定义函数
  3. 可以写成ListNode,不需加struct。
    C struct ListNode是类型。
    C
//C++兼容C结构体的用法。
typedef struct ListNode
{
  int val;
  struct ListNode* next;
}LTN;

C++

//C++把结构体升级成类
struct ListNode//声明这是个类,struct关键字不能去掉
{
  int val;
  ListNode* next;//后面想用这个类型的时候可以去掉。
};

如何用类?
C数据和方法分离,C++方法可以在类的里面

struct Stack
{
//成员函数
//成员函数直接定义到类里面
	void Init(int n=4)//缺省值
	{
		a = (int*)malloc(sizeof(int) * n);
		if (nullptr == a)
		{
			perror("malloc申请空间失败");
			return;
		}
		capacity = n;
		size = 0;
	}
	void Push(int x)
	{
		//...
		a[size++] = x;
	}
	//成员变量
	int* a;
	int size;
	int capacity;
};
int main()
{
	Stack st;//对象
	//如何调用函数?
	st.Init(4);
	st.Push(1);
	st.Push(2);
	st.Push(3);
	st.Push(4);
	return 0;
}

C++可以用struct定义类,但更喜欢用class定义类。

3.类的定义

class className
{
  //类体:包括成员函数(类的方法)和成员变量(类的属性)
}//一定要注意后面的分号!!!!
  • class:定义类的关键字
  • className:类名
  • {}:类的主体
  • 类体中的内容:类的成员
    定义一个声明和定义分离的类。
    缺省参数生命和定义不能同时给,一般在声明给。
    Stack.h
#pragma once
#include <string.h>
#include <stdlib.h>
//类成员函数声明和定义分离
struct Stack
{
	//成员函数
	void Init(int n = 4);//缺省参数在声明给

	void Push(int x);//类的声明
	//成员变量
	int* a;
	int size;
	int capacity;
};

Stack.cpp

#include "Stack.h"
void Stack::Init(int n)//Stack告诉编译器Init不是全局函数,是栈这个类的成员函数
{
	a = (int*)malloc(sizeof(int) * n);//看栈这个类里有没有a这个成员变量
	if (nullptr == a)
	{
		perror("malloc申请空间失败");
		return;
	}
	capacity = n;
	size = 0;
}
void Stack::Push(int x)
{
	//...
	a[size++] = x;
}

用class Stack却编不过,为什么呢?
此时要用到访问限定符。

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

4.1访问限定符

C++访问限定符有三种:公有保护和私有,现阶段保护和私有没有区别。共有及在类外可以直接访问。保护和私有在类里可以访问,类外不可访问。

公有保护私有
publicprotectprivate
  1. 访问限定符不会限定在类里面的访问,锁外面的人不锁里面的人。
  2. 类里面可以有多个访问限定符,限定从该访问限定符到下一个访问限定符出现时位置,如果没有下一个访问限定符则到}结束。
  3. class的默认访问限定符是私有,struct是公有(因为struct要兼容C)。所以上一文中报错了。
    实际生活中不希望默认,希望大家指清楚到底是私有还是公有。
    注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。
#pragma once
#include <string.h>
#include <stdlib.h>
struct Stack
{
publicvoid Init(int n = 4);
	void Push(int x);
privateint* a;
	int size;
	int capacity;
};

大多数情况下成员变量都是私有的,成员函数不给别人用的是私有,给别人用的是公有。
C++中struct和class没有区别,但是struct可以像C语言去用。
Test.cpp

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

};
int main()
{
	Stack st;

	Date d1;
	d1.Init(2023, 2, 3);//调用函数,年月日被初始化
	return 0;
}

4.2封装

【面试题】:面向对象的三大特性:封装,继承,多态
封装:将下面的细节藏起来,本质是一种更好的管理。
C++的封装:将数据和方法都放在类里面去了,即当前封装的极限,并把自己想访问的定义成共有,不想的定义成私有和保护。

5.类的作用域

类定义出一个新的作用域(类域)。

class Person
{
 public:
   void PrintPersonInfo();
 private:
   char _name[20];
   char _gender[3];
   int _age;
};
void Person::PrintPersonInfo()//PrintPersonInfo属于Person这个类域
{
  cout<<_name<<" "<<_gender<<" "<<_age<<endl;//此时可以调用私有
}

6.类的实例化

即用类类型
声明即要定义这个函数或变量,这个变量的类型是什么,名称是什么,参数是什么,但实际这个变量没有出来。定义即把其实实在在在的空间给开出来(对于变量而言)。
类就像一个别墅的设计图,设计了细节,但不能住人,实例化即根据设计图建造出一栋栋别墅。
在这里插入图片描述

class Date
{
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}//函数的定义
private:
	int _year;
	int _month;
	int _day;//声明,没有开空间

};

只需要计算成员变量的大小。

int main()
{

	//类对象实例化--开空间
	Date d1;//定义才是开空间,对于对象整体定义。
	//Date._year=1;
	//Date::year=0;
	//以上两种不可以,声明内不可存数据。
	//d1._year=1;//也不行,访问限定符是私有的。访问不了,访问的时候需要调用这个函数。改成公有就可以了。
	d1.Init(2023,9,12);//Init函数存在哪里呢?
	d1._year++;
	cout<<sizeof(d1)<<endl;
	//类对象大小要考虑内存对齐规则
	return 0;
}//输出12

为什么成员变量存在对象里面,成员函数不存在对象里面?
每个对象的成员变量不一样,需要独立存储。
每个对象调用的成员函数一样,放到共享公共区域(代码段)。
只需要计算成员变量的大小。

//类中既有成员变量,又有成员函数
class A1{
pubic:
 void f1(){}
private:
 int a;
};//sizeof(A1):4
//类中仅有成员函数
class A2{
public:
 void f2(){}
};//sizeof(A2):1//【考点】如果是0,A2 aa1;没有实例化,不能取地址
//类中什么也没有
class A3
{}//sizeof(A3):1,这一个字节用来进行占位,不存储有效数据,标识对象存在过,被实例化定义出来了。

没有成员变量的类都是一个字节

6.2结构体内存对齐规则

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

7.this指针

原来代码:

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

编译器处理完:

class Date
{
public:
		void Init(Date*this,int year, int month, int day)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}

原来代码:

int main()
{
	Date d1;
	Date d2;
	d1.Init(2023, 2, 3);
	d2.Init(2022, 2, 3);

	return 0;
}

编译器处理完:

int main()
{
	Date d1;
	Date d2;
	d1.Init(&d1,2023, 2, 3);
	d2.Init(&d2,2022, 2, 3);

	return 0;
}

如果是d1调用,this是d1的地址,赋值给d1的年月日。
不可以自己去加。

//可以在类里使用this,但是实参和形参里不可以
cout<<this<<endl;
this->_year = year;
this->_month = month;
this->_day = day;
//一般不会这么写
  1. this存在哪里?–存在对象里面?答案❌。
    在栈上,因为他是形参,隐含的形参,不需要显示写,是编译器自己加的。/VS下通过ecx寄存器。
    程序进行编译,编译后成员变量存在对象里,实例化出一个对象,对象存在上。成员函数不要存在栈中,因为成员函数存在一个公共区域,编译的时候要确定call这个函数的地址,这个地址不在对象中去找,在代码段。因为函数的地址是这些指令的地址,这些指令是存在哪呢?存在于代码段。两个东西完全不一样,要从两个不同的角度理解。一个是指令,一个是指令运行过程中的相关数据。不要把两个东西混在一起。
    《深入理解计算机系统》——修炼内功

7.2this指针的特性

void func()
{
 cout<<this<<endl;
 cou<<"func()"<<endl;
 }
int main()
{
//编译报错 运行崩溃 正常运行
  Date* ptr=nullptr;
  ptr->func();
  //结果:正常运行
  ptr->Init(2023,9,12);//运行崩溃,用this去解引用了this->year
  ptr->_year;//会崩溃,因为_year在对象里面,到指针指向的对象去找,指针是一个空指针,相当于解引用。*ptr).func();//正常运行,ptr真正的意义是传递给this,所以也是正常运行,没有解引用这个行为
  Date::func();//不能这么调用,因为要传递this指针。没有this指针调用。
}

指针调用用箭头,有箭头不一定解引用。函数不在对象里。调用这个函数要call这个地址,这个地址在公共区域去找,公共区域:代码段。
成员函数不可以不用对象去调,直接func()。

  1. 受到类域的限制,一般都不在类域里面去找,只在全局去找。在全局找func找不到
  2. 告诉func是Date的成员函数,调用成员函数要传递this指针,所以没有解引用,但是ptr传递给了this指针(cout<<this<<endl;),所以this指针是一个空,但不会报错,只有发生了恶劣的行为才会报错。
  3. 会不会解引用,取决于要不要在对象中去找,而不是有没有这个符号。
    调用函数一共就需要两个动作,一个是传参,传this指针,一个是调用函数,这两个动作都不涉及要去解引用。
    成员函数不是成员对象。

封装(补充)

C语言和C++真正的区别:数据结构的实现与语言无关

CC++
数据和方法分离的都封装在类里面
名字繁琐简洁
数据访问自由不受限制控制访问方式。愿意给你访问的公有,不愿意私有
底层一样

封装在一起才能通过访问限定符限制。

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

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

相关文章

推荐几款实用的Google浏览器插件

推荐几款实用的Google浏览器插件 1. 阅读翻译插件1.1 Google 翻译1.2 DeepL翻译&#xff08;适合大段落&#xff09; 2. 视频字幕翻译插件2.1 YouTube™ 双字幕2.2 Dualsub——实现双字幕 3. 评论翻译插件3.1 油管评论翻译机 4. Infinity 新标签页 (Pro)5. 附加其他5.1 Octotre…

JDK20 + SpringBoot 3.1.0 + JdbcTemplate 使用

JDK20 SpringBoot 3.1.0 JdbcTemplate 使用 一.测试数据库 Postgres二.SpringBoot项目1.Pom 依赖2.配置文件3.启动类4.数据源配置类5.实体对象类包装类6.测试用实体对象1.基类2.扩展类 7.测试类 通过 JdbcTemplate 直接执行 SQL 语句&#xff0c;结合源码动态编译即可方便实现…

复现SCI文章系列教程 | 文章复现一(IF 7.3):文章讨论与文章分析套路讲解

一、本期复现文章 本系列教程从今天开始&#xff0c;前面想做&#xff0c;但是又没时间。作为佛系博主的我来说&#xff0c;这个系列教程算是一个长久的计划。会涉及医学和植物两大类。本系列教程详细情况可以看《复现SCI文章系列教程》. 我们第一篇复现的文章寻找的是的来自…

Spring MVC:请求转发与请求重定向

Spring MVC 请求转发请求重定向附 请求转发 转发&#xff08; forward &#xff09;&#xff0c;指服务器接收请求后&#xff0c;从一个资源跳转到另一个资源中。请求转发是一次请求&#xff0c;不会改变浏览器的请求地址。 简单示例&#xff1a; 1.通过 String 类型的返回值…

开学季买哪个牌子的电容笔好?ipad触控笔推荐平价

我想很多学生们在新学期开始之前就开始买iPad了&#xff0c;如今&#xff0c;作为iPad主要配件之一的电容笔&#xff0c;功能越来越强&#xff0c;使用的人也越来越多。所以&#xff0c;怎样选择一支质量好&#xff0c;价格便宜的电容笔就成了人们最为关注的问题。所以&#xf…

软件测试需求分析

1.1 需求的重要性 1.1.1 软件缺陷的8020原则 1) 在软件测试过程中&#xff0c;从需求分析开始到集成测试阶段引入测试手段&#xff0c;能发现所有缺陷的80%&#xff1b;系统测试阶段引入测试手段&#xff0c;能发现剩余缺陷中80%的缺陷&#xff1b;在运行维护阶段经过长…

云服务器与http服务器

如何与http服务器建立连接&#xff08;客户端&#xff09;&#xff1f; http请求设计格式&#xff1a; 例子&#xff1a; 发送http请求 http数据响应格式&#xff1a; 接收http服务器返回的数据需要进一步进行字符串处理操作&#xff0c;提取有用的数据。

21天学会C++:Day8----范围for与nullptr

目录 ​编辑 1. 范围for 2. nullptr 1. 范围for 我们在写C语言循环遍历代码的时候&#xff0c;无论是用 for循环&#xff0c;while循环都需要考虑循环的起始条件&#xff0c;循环变量的递增逻辑&#xff0c;循环的结束条件。麻烦不说还可能会出错。 int main() {int arr[]…

2023-09-11 LeetCode每日一题(课程表 III)

2023-09-11每日一题 一、题目编号 630. 课程表 III二、题目链接 点击跳转到题目位置 三、题目描述 这里有 n 门不同的在线课程&#xff0c;按从 1 到 n 编号。给你一个数组 courses &#xff0c;其中 courses[i] [durationi, lastDayi] 表示第 i 门课将会 持续 上 durati…

MySQL版数据库原理与应用期末复习重点(1)---关系代数(除运算和自连接查询、手写例题)

文章目录 一、除运算题目二、自连接查询 一、除运算题目 注&#xff1a;在除运算中就包含了选择和投影运算。 二、自连接查询 注&#xff1a;自连接查询一般很少用到。

引爆效率!新一代搜索引擎软件助您快速获取关键数据

一款突破性的搜索引擎软件&#xff0c;助您轻松检索相关数据 →→MsrayPlus官方网址 您是否曾为从海量信息中筛选出关键数据而烦恼&#xff1f;现在&#xff0c;我们为您推出一款全新的搜索引擎软件&#xff0c;让您从繁杂的搜索结果中快速捕捉所需信息。这款软件拥有三大功…

电脑网络不能用?解决99%的网络连接问题...

公文&#xff1a;网络又不能用了&#xff1f; 检查设备连接 首先&#xff0c;我们需要确保所有的网络设备都正确连接。检查以下几点&#xff1a; 路由器状态&#xff1a;确保路由器的电源开关打开&#xff0c;并且显示灯在正常工作。 网线连接&#xff1a;检查所有网线连接…

.Net MVC 使用Areas后存在相同Controller时报错的解决办法; 从上下文获取请求的Area名及Controller名

先来说个额外的问题&#xff1a;如何在请求上下文&#xff08;比如过滤器的中&#xff09;获取请求对应的Area和Controller 名字&#xff1f;&#xff08;假设请求上下文对象为 filterContext &#xff09;&#xff1a; 1. 获取Area名: (string)filterContext.RouteData.DataTo…

山西3D数字化企业品牌展馆

为持续扩大展览群众性和覆盖面、强化影响力和传播力&#xff0c;让更多群众方便快捷、丰富生动地体验展览&#xff0c;展览办委托中央广播电视总台央视网建设了展览数字化网上展馆&#xff0c;通过网络手段&#xff0c;全要素呈现展览内容&#xff0c;全景式还原现场体验&#…

腾讯云2核4G服务器5M带宽 218元一年 优惠价格明细表

腾讯云2核4G服务器5M带宽可以选择轻量应用服务器或云服务器ECS&#xff0c;轻量2核4G5M带宽服务器218元一年&#xff1a; 腾讯云2核4G服务器5M带宽收费 腾讯云2核4G服务器可以选择轻量应用服务器或者ECS云服务器&#xff0c;云服务器ECS是专业级云服务器&#xff0c;大多数使用…

STM32-HAL库06-硬件IIC驱动FM24CL16B非易失存储器

STM32-HAL库06-IIC驱动FM24CL16B非易失存储器 一、所用材料&#xff1a; STM32VGT6自制控制板 STM32CUBEMX&#xff08;HAL库软件&#xff09; MDK5 二、所学内容&#xff1a; 通过HAL库的硬件IIC对FM24CL16B存储器进行写与读取操作。 三、CUBEMX配置&#xff1a; 第一步…

C++继承相关应用练习

1、 实现一个图形类&#xff08;Shape&#xff09;&#xff0c;包含受保护成员属性&#xff1a;周长、面积&#xff0c; 公共成员函数&#xff1a;特殊成员函数书写 定义一个圆形类&#xff08;Circle&#xff09;&#xff0c;继承自图形类&#xff0c;包含私有属性&#xf…

试试用Markdown来设计表单

相信很多后端开发。对于前端知识是比较零碎的&#xff0c;所以很多时候写表单这样的工作&#xff0c;一般就是复制黏贴&#xff0c;然后改改字段。对于HTML格式&#xff0c;一直觉得比较杂乱&#xff0c;不够简洁。 最近TJ发现了一个有趣的小工具&#xff1a;Create HTML Form…

新手请进,Python是什么,Python简介!

Python 是荷兰人 Guido van Rossum &#xff08;吉多范罗苏姆&#xff0c;中国程序员称其为“龟叔”&#xff09;在 1990 年初开发的一种解释型编程语言。 图1&#xff1a;Python 的标志&#xff08;Logo&#xff09; Python 的诞生是极具戏曲性的&#xff0c;据 Guido 自述记载…

【拼多多API接口开发系列】拼多多商品详情接口:卖家必知的赚钱利器

拼多多&#xff0c;作为中国最大的社交电商之一&#xff0c;为卖家提供了丰富的商品详情接口。这些接口可以帮助卖家快速获取商品信息&#xff0c;提高销售效率。本文将详细介绍如何使用拼多多商品详情接口&#xff0c;以及它的优势和注意事项。 一、拼多多商品详情接口概述 …