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

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

作者头像
_孙同学
发布2024-10-21 21:05:22
860
发布2024-10-21 21:05:22
举报
文章被收录于专栏:技术分享

🐳1.类的定义

1.1 类定义格式

class + 类名 + {}; class为定义类的关键字,定义结束时后面的;不能省略。 类主体中的内容称为类的成员:类中的变量称为成员属性或者成员变量;类中的函数称为类的方法或者成员函数。 定义在类中的成员函数默认为inline。

代码语言:javascript
复制
class Date //class定义类的关键字+类名
{
public:
	//成员函数
	void Init(int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

private:
	//成员变量
	int _year;  //为了区分成员变量,一般习惯上会给成员变量加上特殊的标识符
	int _month; //如_或者m开头
	int _day;
};// ;不能省略

C++中struct也可以定义类,C++中兼容C中struct的用法,同时struct升级成类后struct中就可以定义函数。但是一般推荐用class定义类。

🐳2. 访问限定符

public:修饰的成员可以在类外直接被访问。例如成员函数。 private:修饰的成员在类外不能直接被访问。例如成员变量。 protected:修饰的成员在类外不能直接被访问。

class定义的成员没有访问限定符限制默认为private;struct定义的成员没有访问限定符限制默认为public

🐳3. 类域

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

类域影响的是编译器的查找规则,下面程序中Init如果不指定类Stack,那么编译器就会把Init当作全局函数,编译时找不到arr成员的声明/定义在哪里,编译器就会报错。指定类域Stack,就知道Init时Stack的成员函数,当前域找不到arr等成员,就会去类域中查找。

代码语言:javascript
复制
#include<iostream>

using namespace std;

class Stack
{
public:
	//成员函数
	void Init(int n = 4);//函数声明   (int n = 4)为缺省参数,当声明和定义分离时,缺省值只能声明时给

private:
	//成员变量
	int* arr;
	int capacity;
	int top;
};
//函数声明和定义分离时,需要指定类域
void Stack::Init(int n)
{
	arr = (int*)malloc(sizeof(int) * n);
	if (arr == nullptr)
	{
		perror("malloc fail");
		return;
	}
	capacity = n;
	top = 0;
}

int main()
{
	Stack st;
	st.Init();


	return 0;
}

🐳4. 实例化

4.1 实例化概念

实例化:用类类型在物理内存中创建对象的过程。 类是对对象一种抽象的描述(如同建造房子时的图纸,并没有真实的建造出房子,只是对房子的描述),限定了类中有哪些成员变量,这些成员变量只是声明,并没有分配空间,用类实例化出来的对象才会分配空间。

代码语言:javascript
复制
#include<iostream>
using namespace std;

class Date
{
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Priint()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	//这里只是声明,并没有开空间
	int _year;
	int _month;
	int _day;
};

int main()
{
	//Date实例化出对象d1,d2;
	Date d1;
	Date d2;
	
	d1.Init(2024,9,23);
	d1.Priint();

	d2.Init(2024, 10, 1);
	d2.Priint();

	return 0;
}
4.2 对象大小

类实例化出的每个对象,都有独立的数据空间,所以对象中肯定包含成员变量,那么成员函数呢❓

函数被编译后是一段指令,显然对象中是无法存储的,这些指令存储在一个单独的区域(代码段),要存储的话只能存储函数的指针,显然对象中存储函数指针是没有必要的,像上面代码中的d1d2的成员函数InitPrint指针是一样的,如果Date实例化出100个对象,那么函数指针就被重复存储100次,显然十分的浪费。

其实函数指针是不需要被存储的,函数指针是一个地址,调用时被编译成汇编指令【call地址】 ,编译器在编译链接时就会找到函数地址,不是在运行时找的,只有动态多态在运行时找。

📙 内存对齐规则 🍃第一个成员在与结构体偏移量为0的地址处。 🍃其他成员变量要对齐到对齐数的整数倍的位置处。 🍂**对齐数 = 编译器默认的对齐数 与 该成员大小的 较小值 ** 🍃结构体总大小:最大对齐数(所有成员变量最大者与默认对齐参数取较小)的整数倍。 🍃如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

🐳5. this指针

this指针是C++中一个隐含的指针,编译器编译后,类的成员函数默认都会在形参的第一个位置增加一个当前类类型的this指针,比如Date类的Init的真实原型为,viod Init( Date* const this,int year,int month,int day ) 🐾 类的成员函数访问成员变量本质上都是通过 this指针访问的,如Init函数中给_year赋值,this->_year = year 🐾C++规定不能在函数声明和定义时显示写this,但可以在函数体内显示使用this指针

代码语言:javascript
复制
class Date
{
public:
	// 原型viod Init(Date* const this,int year,int month,int day)
	void Init(int year,int month,int day)
	{
		_year = year;  // 相当于this->_year = year;
		_month = month;
		_day = day;
	}

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🐳1.类的定义
    • 1.1 类定义格式
    • 🐳2. 访问限定符
    • 🐳3. 类域
    • 🐳4. 实例化
      • 4.1 实例化概念
        • 4.2 对象大小
        • 🐳5. this指针
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档