类和对象,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.hqwc.cn/news/256153.html

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

相关文章

RHEL8---文件系统

本章主要介绍文件系统的管理 了解什么是文件系统对分区进行格式化操作挂载分区查找文件 在Windows系统中&#xff0c;买了一块新的硬盘加到电脑之后&#xff0c;需要对分区进行格式化才能使 用&#xff0c;Linux系统中也是一样&#xff0c;首先我们要了解一下什么是文件系统。…

无敌是多么的寂寞!一本书讲透Java多线程!吊打多线程从原理到实践!

摘要 互联网的每一个角落&#xff0c;无论是大型电商平台的秒杀活动&#xff0c;社交平台的实时消息推送&#xff0c;还是在线视频平台的流量洪峰&#xff0c;背后都离不开多线程技术的支持。在数字化转型的过程中&#xff0c;高并发、高性能是衡量系统性能的核心指标&#xff…

花生壳安装在ubuntu下,记住要SN号登陆

在ubantu18.0.4上下载花生壳 进入花生壳的下载链接 选择linux版本进行下载 记住选ubuntu 运行命令phddns start

交易历史记录20231207 记录

昨日回顾&#xff1a; select top 10000 * from dbo.全部&#xff21;股20231207_ALL where 连板天 >1 and DDE大单净量>0 and DDE散户数量<0 and RSI> 80 and 五指标共振>0 and 涨停基因>20 and CONVERT(datetime,最后涨停时间,120) <CONVERT(d…

(NeRF学习)3D Gaussian Splatting Instant-NGP

学习参考&#xff1a; 3D Gaussian Splatting入门指南【五分钟学会渲染自己的NeRF模型&#xff0c;有手就行&#xff01;】 三维重建instant-ngp环境部署与colmap、ffmpeg的脚本参数使用 一、3D Gaussian Splatting &#xff08;一&#xff09;3D Gaussian Splatting环境配置…

[Kubernetes]1.Kubernetes(K8S)介绍,基于腾讯云的K8S环境搭建集群以及裸机搭建K8S集群

一. Kubernetes(K8S)简介 Kubernetes (K8S) 是一个为 容器化应用 提供 集群部署 和 管理 的开源工具,和docker swarm类似,由 Google 开发. Kubernetes 这个名字源于希腊语,意为 “ 舵手 ” 或 “ 飞行员 ” , k8s 这个缩写是因为 k 和 s 之间有八个字符的关系, Google…

在线学习平台-班级模块

在线学习平台-项目搭建 在线学习平台-需求分析 若依的基本使用 通过分析可知,班级模块的结构会比较简单,可以先从班级模块入手 1.先在domain里写上班级里的属性 快捷方式: 时区可以这里找,时区和数据库名之间要加一个 ? 右键需要的数据库模型,便可直接生成 生成的实体类不…

Javaweb | Servlet编程

目录: 1.认识Servlet2.编写Servlet3.Servlet的运行机制4.Servlet的生命周期4.1 Servlet生命周期图init()方法doGet()doPost()service()destroy()方法 5.解决“控制台”打印中文乱码问题6.Servlet 和 JSP内置对象 (常用对象)获得out对象获得request 和 response对象获得session对…

文件同步及实现简单监控

1. 软件简介 rsync rsync 是一款开源的、快速的、多功能的、可实现全量及增量的本地或远程 数据同步备份的优秀工具。在同步备份数据时&#xff0c;默认情况下&#xff0c;Rsync 通过其 独特的“quick check”算法&#xff0c;它仅同步大小或者最后修改时间发生变化的文 件或…

设备间的指令通信

指令通信的概念 要进行设备和设备之间的交流就需要通过串口发送数据进行交流 而串口发送简单的数据只需要传输介质 但是要发送复杂的数据就需要介质和传输的规则了 三种应用场景 比如在上位机和mcu之间 通过上位机管理控制器 从而控制电池 单片机和单片机之间 用户输入数据到…

Ubuntu安装nvidia GPU显卡驱动教程

Ubuntu安装nvidia显卡驱动 1.安装前安装必要的依赖 sudo apt-get install build-essential sudo apt-get install g sudo apt-get install make2.到官网下载对应驱动 https://www.nvidia.cn/Download/index.aspx?langcn 3.卸载原有驱动 sudo apt-get remove --purge nvidi…

【Linux】公网远程访问AMH服务器管理面板

目录 1. Linux 安装AMH 面板2. 本地访问AMH 面板3. Linux安装Cpolar4. 配置AMH面板公网地址5. 远程访问AMH面板6. 固定AMH面板公网地址 AMH 是一款基于 Linux 系统的服务器管理面板&#xff0c;它提供了一系列的功能&#xff0c;包括网站管理、FTP 管理、数据库管理、DNS 管理、…