C++(上): 类和对象的初识

“我知道攀登高峰的崎岖变得越难越难走”

————————《西门少年》


在C++的学习中,掌握类和对象,是打开Cpp学习的敲门砖。

(1)类的引入:

①struct:

我们知道,在C中可以用结构体 struct 定义一个多种类型的集合:

strcut A
{
  int a;
  char* pa;
  double b;
};

那么在C++中我们也继承了C的传统,另外在struct中,除了定义变量,还可以定义函数

struct A
{
    //定义的函数
	int Add(int a, int b)
	{
		return a + b;
	}

	void PrintA()
	{
		cout << "PrintA()" << endl;
	}

   //变量声明
	char _a[10];
	int _b;
	int _c;
};

因为这里为了区别,c++中 更喜欢用class 来 替代struct。

②class:

形如struct,class 和struct类似.

        
class B//类名
{
    //成员函数 或者 类的方法
	void PrintB()
	{
		cout << "PrintB()" << endl;
	}

   //成员变量
	int _a;
	char* pc;
};

根据上图,可以确定一个 类的元素是由,成员变量、成员函数构成。


(2)类的定义:

在上面代码的展示里面,都是类定义的一种。其实类定义分为两种

1.声明和定义全部放在类体中,需要注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。

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

不过在类外定义函数的时候,要用"::" 指定类域。类域左边是返回值,右边是函数名。 


(3)类的访问以及权限:

C++相对于 C 更加安全就在于,在C++的类引入了限定符。

C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。

①pubilc:就是公共区域,类外类内都可以调用。

②proted和private在现在,我们统一都理解为一个意思。类外不能直接访问。

(一)struct 与 class 默认权限的区别:

此时我们可以对struct内部进行访问。

 然而,当我们用class 的时候,则不会让类外成员直接访问。

所以我们总结:

class的默认访问权限为private,struct为public。

所以,让类外 访问进class里的内部,也就只需要 改变就行。


 (4)类的作用域以及类的大小:

在类的定义中,引入了类域的概念。

在类体外定义成员,需要使用 :: 作用域解析符 指明成员属于哪个类域。

class Person
{
public:
	void PeopleInfore();

private:
	char _name[10];
	int _age;
	char _sexy[5];
	int number;
};

//声明类域
void Person::PeopleInfore()
{
	cout << _name << _age << number;
}

类的大小:

那么,如果类里没有变量成员,大小又该是多少呢?!

可以看出,当类为空空类时,仍然占有一字节。此时的一字节不是具体内存大小。而是作为占位存在。 

类里的成员函数是否也占有大小呢?那成员函数存储在什么区域?

答案是,类大小的计算不包含成员函数。

因为,每个类 调用的都是同样一个成员函数,但是有不同的成员变量。所以,如果每次创建一个类,就要为成员函数开辟空间,造成空间浪费。因为仅仅需要一份就够了。

一个类,只保存成员变量,成员函数存放在公共的代码段。

 所以计算类的大小,和C中计算结构体大小一样。

内存对齐规则:

1. 第一个成员在与结构体偏移量为0的地址处。

2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。

4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是 所有最大对齐数(含嵌套结构体的对齐数)的整数倍。


(5)this 指针:

在C++中,this指针是一个很重要的概念。

我们先写一个Date(日期) 类;

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


int main()
{
	Date d1;
	d1.InitDate(2022, 6, 21);
	d1.Display();
	Date d2;
	d2.InitDate(2018, 6, 7);
	d2.Display();
    return 0;
}

 很清楚的知道,在类外定义了两个d1 和 d2。他们两个都分别调用同一个成员函数InitDate 和 Display。

但为什么,该函数能分别对d1,d2分别设置呢?!

C++中通过引入this指针解决该问题。

什么是this指针?

this指针,是一个隐藏的指针参数,目的是为了让该指针当前运行的对象,去进行函数的调用和参数的应用。

 

所以我们也可以这样用:

 在每个操作代码前,添加this指针。

那么我们是否可以把这个this指针,在函数参数一栏补充出来呢?

当然是不行的。因为这是编译器自己补充,并不是让用户知晓。

 this指针的特性:

1. this指针的类型:类类型* const。

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

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

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

两个问题:

1. this指针存在哪里? 2. this指针可以为空吗?

1.根据上面特性,第一个问题很简单,this指针是形参,是在调用函数的时候形成的临时拷贝。所以是在保存在栈上。

2.可以看出这个哈拿书可以正常运行

 但运行第一个函数 直接跑死掉。

传过去的this 接收到的是nullptr的空指针,并对空指针, 解引用。所以导致程序崩溃。


别走哦~ 还有下

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值