C++初阶之类与对象(上)详细解析

个人主页:点我进入主页

专栏分类:C语言初阶  C语言进阶  数据结构初阶    Linux    C++初阶    

欢迎大家点赞,评论,收藏。

一起努力,一起奔赴大厂

 

目录

 

一.前言

二.类的定义和使用

2.1类的引入

2.2类的定义和访问限定符

2.21定义

2.2.2访问限定符

2.2.3代码示例以及对上面的分析

2.2.4封装

2.3类的内存对齐

2.3.1类中的函数的位置

2.3.2小问题

2.3.3内存对齐

2.3.4内存对齐意义


 

一.前言

        在前面我们写过C++入门中的函数重载,命名空间,缺省参数,引用,还有一些新的语法, 这些内容是我们学习后面的基础,在今天我主要给大家带来关于类的内容,其中包括类的定义和使用,访问限定符封装,类的实例化,计算类的大小以及内存对齐。

二.类的定义和使用

2.1类的引入

        在c语言期间我们的结构体你还记得吗?在C++中祖师爷对它进行了升级,升级成了我们的类,我们写一个代码表示C语言中的结构体:

struct A {
	int num1;
	int num2;
	int* p;
};

我们定义变量时使用:

struct A a;

如果我们想定义一个函数,我们需要在结构体外进行声明和定义。

那我们在C++中是如何使用结构体呢?我们看下面的代码

struct Data {
	int _year;
	int _month;
	int _day;
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
};

int main()
{
	Data d1;
	d1.Init(2024, 1, 31);
	return 0;
}

在C++中我们更喜欢使用class来定义。

2.2类的定义和访问限定符

2.21定义

        class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。(也就是说我们将class代替我们的struct,当然struct也可以,{}中包含的分为两部分一是成员变量,一部分是成员函数)。

2.2.2访问限定符

        访问限定符包括3个分别是public(公开),private(私有),protected(保护),其中public可以任意访问,protected和private不能任意访问只能在类里面访问,访问权限是从第一个访问限定符到下一个访问限定符之间,struct默认为public,class默认为private。

2.2.3代码示例以及对上面的分析

#include
using namespace std;

class Data {
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1;
	d1.Init(2024, 2, 1);
	d1.Print();
	return 0;
}

        我们采用class的形式,我们的第一个限定词是public第二个限定词是private,其中public的作用域是public到private,private的作用域是从private到结尾。在main函数中我们定义的d1可以称为我们的对象,我们访问public作用域的内容时我们直接利用对象去访问,下面的访问方式是不对的:

	Init(2024, 2, 1);
	Data::Init(2024, 2, 1);

C++初阶之类与对象(上)详细解析_第1张图片

这两种都存在存在问题,都是不正确的,对于public作用域的我们可以在类的里面和外面进行访问   ,那对于private或protect作用域的内容呢?我们看到在定义Init函数时我们在类里面就使用了我们private的内容,因此在类里面可以访问,那类外面呢?我们看下面

	d1._year = 1;
	Data::_year;

这两种都是会报错的

C++初阶之类与对象(上)详细解析_第2张图片

所以我们可以看到private作用域的变量或函数只能在类里面进行访问,不能在类外访问,由于private和protect在这里一样,所以不做过多演示。

2.2.4封装

        我们可以将封装看成一种管控,c++将变量和方法放在类里面,允许让我们访问的使用public进行修饰,不想让我们访问的使用private或protected进行修饰。

2.3类的内存对齐

2.3.1类中的函数的位置

        我们需要知道,类中函数的位置,类中函数和成员变量是放在不同的位置,

C++初阶之类与对象(上)详细解析_第3张图片

如果我们定义一个指针

	Data d1;
	Data* p = &d1;

我们需要知道p指向成员变量。

2.3.2小问题

        我们看下面的代码输出结果是什么:

#include
using namespace std;
class Data {
public:
	void Print()
	{
		cout << "Print()" << endl;
	}
};

int main()
{
	Data d1;
	Data* p = &d1;
	p->Print();
	return 0;
}

很显然我们的结果是Print();

那我们的这行代码输出结果是什么呢?

	Data* p = nullptr;
	p->Print();

 是不是很多人说对空指针的解引用,会导致空指针的解引用,其实这样的结果还是Print(),为什么呢?我们看上面类的成员变量和成员函数是分开的,我们的p是指向我们的成员变量的区域,无论成员变量是什么样子,我们的函数区域是不变的。

	Data* p = nullptr;
	(*p).Print();

我们这个代码个上面的一样,都会正常运行。 

2.3.3内存对齐

        类的内存对齐和我们在前面c语言中的内存对齐一样,在vs中我们的对齐数为8,我们的Data中_year占0,1,2,3的位置,_month占4,5,6,7,。_day占8,9,10,11占12个12是4的倍数所以占12个,在这里不做具体解释,不理解的可以在内存对齐中查看。

2.3.4内存对齐意义

        我们知道了内存对齐,那它有什莫意义呢?我们这样舍弃空间是为什么呢?我们需要知道一些机器一次只能访问4个或8个字节,我们以4个字节为例,

C++初阶之类与对象(上)详细解析_第4张图片

如果我们一次访问4个字节,第一种没有对齐的int需要访问两次,第一期是前三个字节,第二次要访问第4个字节,而第2种我们能访问int能直接进行访问,这样可以减少我们的访问次数,我们采用内存对齐是一种空间换时间的方式,这就是内存对齐的意义。

三.this指针

        this指针是默认生成的,类型为*const 我们不能在形参和实参的位置显示写,但函数种可以用,这是this指针的定义,我们看一看相关代码

#include
using namespace std;

class A {
public:
	A(int a = 1)
	{
		_a = a;
	}
	void Print(A*const this)
	{
		cout << _a << endl;
	}
private:
	int _a;
};

int main()
{
	A a;
	a.Print(this);
	return 0;
}

我们的代码就会报错,错误如下:

C++初阶之类与对象(上)详细解析_第5张图片

如果我们将Print函数中加上this呢?

	void Print()
	{
		cout < _a << endl;
	}

程序就会正常运行。 

四.总结

        今天的内容就结束了,这些都是类的基础,大家可以认真看看,对于后面的内容非常重要。最后希望大家可以一键三连。

 

你可能感兴趣的:(C++初阶,c++)