类和对象,this指针

一、类的引入:

如下,在C++中,我们可以在结构体中定义函数,如下,之前我们学习C中中一直是在结构体中定义变量。

struct student{void studentinfo(const char* name,const char* gener,int age){ strcpy(_name,name);strcpy(_gener,gener);strcpy(_age,age);}void printstudent(){cout<<_name<<" "<<_gener<<" "<<_age<<endl;}char _name[20];char _gener[3];int  _age;}

上面结构体的定义,在C++中更喜欢用class代替struct 。

二、类的定义

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

类中的元素称为类的成员:
类中的数据称为类的属性或成员变量
类中的函数称为类的方法或成员函数

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

类定义的两种方式:

  1. 声明和定义全部放在类体中,需要注意:成员函数如果在类中定义,编译器可能会把其当成内联函数(隐式定义)处理。
class student
{
public:void studentinfo(const char* name, const char* gener, int age){strcpy(_name, name);strcpy(_gener, gener);_age = age;}void print(){cout << _name << " " << _gener << " " << _age << endl;}
private:char _name[20];char _gener[3];int _age;
};
  1. 更多的采用的下面的方式:
    .c文件
 void student :: studentinfp( const char* name, const char* gener, int age){strcpy(_name, name);strcpy(_gener, gener);_age = age;
}
void student :: print()
{cout << _name << " " << _gener << " " << _age << endl;
}

.h文件

class student
{public:void studentinfo(const char* name, const char* gener, int age); void print();private:char _name[20];char _gener[3];int _age;}

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

3.1 访问限定符

访问限定符:

public(公有) private(私有) protected(保护)

访问限定符说明:
public修饰的成员在类外可以直接被访问
protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
class的默认访问权限为private,struct为public(因为struct要兼容C)

struct和class的区别:
struct可以定义结构体,也可以和class一样定义类,定义方法也是一样的,区别在于struct的默认权限是public,class的默认权限是private。

3.2 封装

面向对象的三大特性:封装;继承;多态
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

封装本质上是一种管理:我们如何管理兵马俑呢?比如如果什么都不管,兵马俑就被随意破坏了。那么我们首先建了一座房子把兵马俑给封装起来。但是我们目的是全封装起来,不是不让别人看。所以我们开放了售票通道,可以买票突破封装在合理的监管机制下进去参观。类也是一样,我们使用类数据和方法都封装到一下。不想给别人看到的,我们使用protected/private把成员封装起来。开放一些共有的成员函数对成员合理的访问。所以封装本质是一种管理。

如:

class student
{ 
public://公有成员,可以被外部访问void studentinfo(const char* name,const char* gener,int age){cout<<_name<<" "<<gener<<" "<<age<<endl;}
private://私有成员,不允许被外部直接访问和修改char _name[20];char _gener[3];int age;
};

四、类的作用域

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

class Person
{
public:
void PrintPersonInfo();
private:
char _name[20];
char _gender[3];
int _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{
cout<<_name<<" "_gender<<" "<<_age<<endl;
}

五、类的实例化

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

  1. 类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它
  2. 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量
  3. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。
    在这里插入图片描述
#include<iostream>
using namespace std;
class student
{
public:void studentinfo(const char* name, const char* gener, int age){strcpy(_name, name);strcpy(_gener, gener);_age = age;}void print(){cout << _name << " " << _gener << " " << _age << endl;}
private:char _name[20];char _gener[3];int _age;
};
int main()
{student s1;//实例化对象1s1.studentinfo("王二麻","男",17);student s2;//实例化对象2s2.studentinfo("赵四","男",18);return 0;
}

六、类对象的存储方式及大小计算

6.1存储方式

存储方式:只保存成员变量,成员函数放在公共代码区

优点::每个对象中成员变量是不同的,但是调用同一份函数,如果按照此种方式存储,当一个类创建多个对象时,都调用同一份函数,会节省很多空间。
在这里插入图片描述

6.2 大小计算
// 类中既有成员变量,又有成员函数
class A1 {
public:
void f1(){}
private:
int _a;
};
// 类中仅有成员函数
class A2 {
public:
void f2() {}
};
// 类中什么都没有---空类
class A3
{};

izeof(A1) : ______ sizeof(A2) : ______ sizeof(A3) : ______
类中的成员函数由于存放在公共代码段中,所以在计算类的大小时不包含成员函数的大小。

而对于成员变量,计算方法和C语言中对结构体大小的计算方法一致。

对于没有成员变量的类和空类,类中没有成员变量,按照前面的做法他的大小为0,那么内存将不会为他分配空间。但是这个类确实是存在的,存在就应该为他分配空间。在这里,会为他分配1个字节的空间。
在这里插入图片描述
结论:一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类。

七、this指针

7.1 this指针的引出

我们先来定义一个日期类Date:

class Date
{
public :void Display (){cout <<_year<< "-" <<_month << "-"<< _day <<endl;}void SetDate(int year , int month , int day){_year = year;_month = month;_day = day;}
private :int _year ; // 年int _month ; // 月int _day ; // 日
};int main()
{Date d1, d2;d1.SetDate(2018,5,1);d2.SetDate(2018,7,1);d1.Display();d2.Display();return 0;
}

对于上述类,有这样的一个问题:
Date类中有SetDate与Display两个成员函数,函数体中没有关于不同对象的区分,那当d1调用SetDate函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?

上述代码调用成员函数传参时,看似只传入了一些基本数据,实际上还传入了指向该对象的指针:
在这里插入图片描述
编译器进行编译时,看到的成员函数实际上也和我们所看到的不一样,每个成员函数的第一个形参实际上是一个隐含的this指针,该指针用于接收调用函数的对象的地址,用this指针就可以很好地访问到该对象中的成员变量:
在这里插入图片描述

7.2 this指针的特性

this指针的类型:类类型* const

只能在“成员函数”的内部使用

this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。

this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递

在这里插入图片描述
this指针一般存放在栈中,不同的编译器不同;
this指针可以为空

文章参考:
https://blog.csdn.net/m0_58367586/article/details/123017101

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

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

相关文章

一个类似connectedpapers的文献知识图谱神器:Libraries S2

在阅读文献、写综述、写论文的related works的时候&#xff0c;总会苦恼如何查阅该领域的论文呢&#xff1f;怎么才能尽可能的查找齐全&#xff1f; 以前在看论文的时候&#xff0c;我都是先用谷歌学术搜索&#xff0c;然后看到优秀的相关文文献后&#xff0c;再去查看它的参考…

java应用在Windows服务器运行时控制台输出日志中文乱码终极解决办法

修改注册表&#xff0c;适用于cmd&#xff0c;在各种开发工具终端中均生效 第一步、按winr&#xff0c;输入regedit运行&#xff0c;进入注册表界面 第二步、找到【HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor】 第三步、新建一个表项&#xff0c;命名为autor…

世微 AP3266 大功率同步降压恒流芯片 过EMC 车灯驱动

产品描述 AP3266 是高效率、外围简单、内置功率管的同步降压恒流芯片&#xff0c;适用于4-40V输入的降压LED恒流驱动芯片。输出最大功率可达 40W&#xff0c;最大电流3.6A。AP3266 可通过调节 OVP 端口的分压电阻&#xff0c;设定输出空载电压 保护&#xff0c;避免高压 空载上…

深入探索Python delattr函数的威力与灵活性

引言&#xff1a; 在Python中&#xff0c;delattr函数是一个非常强大且灵活的工具&#xff0c;它允许我们删除对象的属性。使用delattr函数&#xff0c;我们可以动态地删除对象的属性&#xff0c;从而在编程中实现更灵活的操作。本文将详细介绍delattr函数的用法&#xff0c;帮…

Python Struct 模块:二进制数据的强大解析与打包工具

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python中的struct模块是一个强大而灵活的工具&#xff0c;用于解析和打包二进制数据。本文将深入介绍struct模块的各个方面&#xff0c;通过丰富的示例代码&#xff0c;帮助读者更全面地理解和运用这一模块&…

98基于matlab的在MIMO通信系统中功率优化算法的仿真

基于matlab的在MIMO通信系统中&#xff0c;功率优化算法的仿真&#xff0c;重点研究了注水功率分配算法。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 98matlab功率优化功率分配 (xiaohongshu.com)

代码随想录二刷 | 栈与队列 | 前 k 个高频元素

代码随想录二刷 &#xff5c; 栈与队列 &#xff5c; 前 k 个高频元素 题目描述解题思路 & 代码实现 题目描述 347.前k个高频元素 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nu…

前端项目中CDN的一些问题【性能优化篇】

1. CDN的概念 CDN&#xff08;Content Delivery NetWork&#xff0c;内容分发网络&#xff09;&#xff0c;是指利用最靠近每位用户的服务区&#xff0c;更快的将资源发送给用户。 提高用户的访问速度减轻服务器压力提高网站的稳定性和安全性 2. CDN的作用 CDN一般用来托管…

【从零认识ECS云服务器 | 快速上线个人网站】阿里云手动搭建WordPress网站

第一步&#xff1a;部署 LAMP/LNMP 环境&#xff0c;需要在ECS实例中安装操作系统&#xff08;Linux&#xff0c;本例中使用的操作系统版本为CentOS 7.9 64位&#xff09;、Web服务器软件&#xff08;Apache/Nginx&#xff09;、数据库软件&#xff08;MySQL&#xff09;、网站…

GIT GUI使用

文章目录 一、新建本地仓库二、推送&#xff08;push&#xff09; 一、新建本地仓库 在空白处右键&#xff0c;找到GIT GUI here&#xff0c; 如果没有仓库&#xff0c;出现的是这样的&#xff1a; 如果有仓库&#xff0c;在本地仓库里打开就是这样的&#xff1a; 新建本地…

探索低代码的潜力、挑战与未来展望

低代码开发作为一种新兴的开发方式&#xff0c;正在逐渐改变着传统的编程模式&#xff0c;低代码使得开发者无需编写大量的代码即可快速构建各种应用程序。然而&#xff0c;低代码也引发了一系列争议&#xff0c;有人称赞其为提升效率的利器&#xff0c;也有人担忧其可能带来的…

代码随想录算法训练营 ---第五十八天

今天开启单调栈的征程。 第一题&#xff1a; 简介&#xff1a; 本题有两种解法&#xff0c;第一种&#xff1a;暴力破解 两层for循环 时间复杂度为O(n^2) 超时了 第二种&#xff1a;单调栈解法也是今天的主角。 单调栈是什么&#xff1f; 单调递增栈&#xff1a;单调递增栈…

卡通渲染总结《三》

接上回 卡通渲染总结《二》的描边技术&#xff0c;接下就是其绘画&#xff08;The Painter&#xff09;的技术。 Painter 的目的是从 3D 模型中生成平面图像。使用这种方法&#xff0c;可以通过改变阴影和高光参数以及着色计算的权重因子来产生各种样式。 阴影部分 单光源 …

docker网络【重点】

一、网络知识 1、桥接模式&#xff1a;用于链接两个不同网络段的设备&#xff0c;是共享通信的一种方式 2、桥接设备&#xff1a;工作在OSI模型的第二层&#xff08;数据链路层&#xff09;。根据MAC地址转发数据帧&#xff0c;类似于交换机&#xff0c;只能转发同一网段&…

状态设计模式

package com.jmj.pattern.state.after;public abstract class LiftState {protected Context context;public void setContext(Context context) {this.context context;}//电梯开启操作public abstract void open();//电梯关闭操作public abstract void close();//电梯运行操…

双目光波导AR眼镜_AR智能眼镜主板PCB定制开发

AR眼镜方案的未来发展潜力非常巨大。随着技术的进步&#xff0c;AR眼镜的光学模块将变得更小巧&#xff0c;像素密度也会增加&#xff0c;实现更高分辨率的画面&#xff0c;甚至能够达到1080P、2K和4K级别的清晰度&#xff0c;从而提升用户的视觉体验。 AR智能眼镜的硬件方面&a…

河南诗词大会规则和流程

河南省诗词大赛是一场充满诗意的盛会&#xff0c;分为小学组、中学组和社会组。流程包括四个环节&#xff1a;“大浪淘沙” 、“月宫折桂” 、“飞花令”和“诗画南阳”。 比赛前两轮为“大浪淘沙”和“月宫折桂”环节&#xff0c;所有赛手采用平板现场答题&#xff0c;时间为2…

企业培训私有化解决方案PlayEdu

本文应网友 林枫 的要求而折腾&#xff1b; 什么是 PlayEdu &#xff1f; PlayEdu 是一款适用于搭建内部培训平台的开源系统&#xff0c;旨在为企业/机构打造自己品牌的内部培训平台。PlayEdu 基于 Java MySQL 开发&#xff1b;采用前后端分离模式&#xff1b;前端采用 React1…

学习记录---kubernetes中备份和恢复etcd

一、简介 ETCD是kubernetes的重要组成部分&#xff0c;它主要用于存储kubernetes的所有元数据&#xff0c;我们在kubernetes中的所有资源(node、pod、deployment、service等)&#xff0c;如果该组件出现问题&#xff0c;则可能会导致kubernetes无法使用、资源丢失等情况。因此…

104.进程创建

目录 进程创建相关的函数 获取当前进程的进程ID&#xff08;PID&#xff09; 获取当前进程的父进程ID&#xff08;PPID&#xff09; 创建一个新的进程 fork()剖析 调用格式 创建子进程 子进程与父进程 父子进程执行流 代码演示 进程创建相关的函数 Linux中进程ID为pi…