前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C++】————类和对象(上)

【C++】————类和对象(上)

作者头像
用户11036582
发布2024-06-28 09:31:13
870
发布2024-06-28 09:31:13
举报
一、类与对象的初步认识

1、类其实就是对对象的抽象,而对象就是对类的具体实例

类不占用内存,而对象占用内存。

2、面向对象与面向过程

C语言是面向过程的,关注的是过程中的数据与方法。

C++是面向对象的,关注的是对象’的属性与功能。

在C语言中不能再结构体中包含函数,但是在C++中却可以。

代码语言:javascript
复制
struct student
{
	char _name[20];
	int _age;
	void SetStudentInfo(const char *name, int age)
	{
		strcpy(_name, name);
		_age = age;
	}
};

其实这里的结构体就是类,C++中兼容C语言中结构体用法,同时增加了类的用法

其实和C语言最大的区别就在于: C语言中struct只可以定义变量,C++中的struct既可以定义变量,也可以定义函数(实现方法)。

二、类的定义

其实在我们实际的开发中呢,我们不会去使用struct去定义类,而是使用class,下面我们来看一下它的用法。

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

这里的class就是定义类的关键字,classname就是这个类的名字。

注意:类的成员函数默认是内联(即是内联函数)的。

类的两种定义方式:

1、类和声明都放在类体中:

代码语言:javascript
复制
class Person
{
public:
	//显示基本信息
	void showInfo()
	{
		cout << _name << "-" << _age << endl;
	}
public:
	char* _name;
	int _age;
};

2、类的声明放在.h文件中,类放在.cpp中

代码语言:javascript
复制
声明放在类的头文件person.h中
class Person
{
public:
	//显示基本信息
	void showInfo();
public:
	char* _name;
	int _age;
};

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

C++的三大特性就是:封装、继承、多态,我们在这里先只说一下这个封装。

要想了解封装,首先我们要知道它的概念:将数据和操作数据进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。我相信大家看到这里也是一脸懵,我给大家举个例子:博物馆是如何管理的呢?如果不采取措施,文物将被损坏。所以我们就建立了一个博物馆,把文物都封装起来,不让人们看。但是我们开放了购票机制,可以买票突破封装进去参观。这就和类一样,我们使用类数据和方法都封装到一下。不想给别人看到的,我们使用protected/private把成员封装起来。开放一些共有的成员函数对成员合理的访问。所以封装本质是一种管理。

这里我们就要提到三个访问限定符:

访问限定符说明:

  1. public:public是公有操作符,听他的名字就知道,都可以去访问,所以public修饰的成员可以在类外直接访问。
  2. protected和private修饰的不可以在类外直接被访问(此处的两者作用相同)
  3. 访问权限是从改访问限定符出现到下一个访问限定符出现为止
  4. 在class中,默认的访问权限是private,struct中是public,这也是这两者的区别

注意访问限定符只在编译时有用,当数据映射到内存后,没有任何限定符之间的区别。

四、类的实例化

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

  1. 类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它
  2. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
  3. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。

四、类的大小

一个类中既包含了成员函数,又包含了成员变量,那么一个类的实例化对象中包含了什么?怎么计算一个类的大小?

只保存成员变量,成员函数存放在公共的代码段,通过指针的方式来找到成员函数。当然这里也遵循内存对齐原则。

代码语言:javascript
复制
class A1 {//占四个字节
public:
   void f1() {}
private:
   int _a;
};

// 类中仅有成员函数
class A2 {//占一个字节
public:
 void f2() {}
};

class A3
{};

空类的大小:空类占1个字节,占位用,告诉系统我这里定义了一个类,虽然它是空的。

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

不清楚内存对齐原则的,可以去看一下这篇文章:内存对齐原则

五、this指针

首先我们看一下这串代码:

代码语言:javascript
复制
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(2022, 5, 11);
	d2.SetDate(2022, 5, 12);
	d1.Display();
	d2.Display();
	return 0;
}

运行之后结果是这样的:

我们可以通过汇编来看一下:

我们可以发现,最终打印的时候调用的Display()是同一个函数, 那么既然d1,d2调用的都是同一个函数,编译器如何知道d1是2022-5-11,d2是2022-5-12呢?Display()都访问的_year,_month,_day。而且去公共代码区访问的Display(),这是为什么呢?

这是因为C++在这段代码中做出手脚,C++在这里增加了一个this指针,这里是因为Display会增加一个this形参。C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成

在调用的时候也传的是各自的地址。这样就十分清晰明了了。这就是隐含的this指针

在实际中,this指针是被const修饰的,指针本身不能被修改,但是内容可以被修改

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、类的定义
  • 三、类的访问限定符及封装
  • 四、类的大小
  • 五、this指针
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档