🐇
🔥博客主页: 云曦
📋系列专栏:[C++]💨路漫漫其修远兮 吾将而求索 💛 感谢大家👍点赞 😋关注📝评论
文章目录
- 📙前言
- 📙1、面向过程与面向对象的初步认识
- 📙2、类的引入
- 📙3、类的定义
- 📙4、类的访问限定符
- 📙5、类的作用域
- 📙6、类的实例化
- 📙7、类的对象模型
- 📋7.1、类对象的存储方式
- 📙8、this指针
- 📋8.1、this指针的引出
- 📋8.2、this指针的特性
📙前言
哈喽!大家好呀,咱们又见面了。
上期我们也是触摸到了C++的大门,那么这期我们就要开始慢慢的推开这扇大门了。也希望和大家一起坚持学习下去。
📙1、面向过程与面向对象的初步认识
- 我们之前所学的C语言是面向过程的这么一个语言。C语言关注的是过程,分析出解决问题的步骤,然后逐步执行解决问题。
- 就比如我们在手洗衣服时,会有这些步骤:
C++是基于面向对象的,关注的是对象,将一件事划分成不同对象,靠和对象之间的交互完成任务。
整个过程就四个对象:人、洗衣机、衣服洗衣服。
人倒入洗衣服和衣服,启动洗衣机,洗衣机就会完成该完成的步骤。
人、洗衣机、衣服、洗衣服四个过程之间是相互交互的,人不关心洗衣机是如何洗衣服、甩干的。
📙2、类的引入
- 在C语言中我们定义一个栈是这样定义的:
struct Stack
{
int* a;
int top;
int capacity;
};
//函数只能写在外面
void StackInit(Stack* st)
{
//...
}
- 现在C++里写栈时,会发现在struct里面是可以定义函数的。
struct Stack
{
int* a;
int top;
int capacity;
void Init();
};
- 这其实就是面向对象:C++把struct叫作类,因为C++包含C的百分之80/90,所以在C++里struct包含了C语言里的所有用法,且C++还对struct进行了升级。但在C++中,定义自定义类型通常都是用class定义的,极少数情况用struct定义。
📙3、类的定义
class className
{
//类体:由成员函数和成员变量组成
};
- class 为定义类的关键字、className 是这个类的名字、{}为类的主体、注意:{}后面的;不能省略。
- 类体中的内容称为类的成员,类里的变量叫作成员变量、类里的函数叫作成员函数。
- 类定义的两种方式:
- 声明和定义都放在类内,但需要注意:在类里定义的成员函数有可能会被编译器当作内联函数处理。
//人
class Person
{
public:
//打印信息
void print()
{
cout << (*_name) << "-" << (*_sex) << "-" << _age << endl;
}
private:
char* _name;//名字
char* _sex;//性别
int _age;//年龄
};
2.声明和定义分离,声明在.h文件里、定义在.cpp文件里。
- 注意:cpp文件里定义的函数需要加 类名::
- 一般情况下都是用第二种方式。
- 成员变量的命名规则(建议)
class Date
{
public:
void Init(int year, int month, int day)
{
//这样你怎么分清楚哪个是类的成员变量,哪个是形参?
year = year;
month = month;
day = day;
}
private:
int year;
int month;
int day;
};
- 所以建议大家在写类的成员变量时,在前面后后面加上_,便于区分。
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
📙4、类的访问限定符
- C++实现封装的方式:用类将对象的属性(成员变量)和方法结合在一起,通过访问权限的方式提供接口给外部的用户使用。
- 公有:类内可以访问,类外也可以访问。
- 保护:类内可以访问,类外不可以访问。
- 私有:类内可以访问,类外不可以访问。
- 在前期,我们就把保护和私有两个权限都当成一样的作用来使用。保护权限要到继承篇才好具体说明。
- class和struct的区别:
- class的默认访问权限是私有的,而struct的默认访问权限是公有的。
- struct包含了C语言struct的功能。
📙5、类的作用域
- 类的作用域就是定义类的{}里面为类的作用域。
class Date
{
//{}内,为类的作用域
private:
int _year;
int _month;
int _day;
};
//{}外,不是类的作用域
- 注意:在类外定义成员时,要用::域作用限定符来指定属于哪个类的。
class Date
{
public:
void Init(int year, int month, int day);
private:
int _year;
int _month;
int _day;
};
void Date::Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
📙6、类的实例化
class Date
{
public:
void Init(int year, int month, int day);
private:
int _year;
int _month;
int _day;
};
- 大家想一下,类内的成员变量是声明还是定义呢?— 是声明
- 那么定义在哪呢?
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
//这样就是类的实例化
//C++把d1叫作对象
Date d1;
return 0;
}
- 可以这样理解:
- 一个类可以有很多个对象,同理一张图纸也可以盖出好几栋一样的房子。
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
//一个类可以实例化多个对象
Date d1;
Date d2;
Date d3;
Date d4;
Date d5;
return 0;
}
📙7、类的对象模型
📋7.1、类对象的存储方式
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
- 大家猜猜上面类的大小是多少?
- —12字节
- C++类的大小和C语言的struct定义类型的大小的计算方式是一样的(都是要内存对齐)。
- 空间是可以重复利用的,所以成员函数不在类开辟的空间内,而是在C++的一个公共代码区内放置成员函数,调用时会去这个公共的代码区寻找函数。
- 如果,成员函数也和成员变量一样开辟空间,那么实例化多个对象时也就开辟了多个一样的函数空间,这样就会造成空间上的浪费。
//空类又是多少字节呢?
class Stack
{};
- 也许大家会认为空类没有开辟空间就是0字节。其实不是,为了证明这个空类存在过C++给空类安排了1字节的空间,来证明这个类存在过。
📙8、this指针
📋8.1、this指针的引出
#include<iostream>
using namespace std;
class Date
{
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()
{
Date d1;
Date d2;
d1.Init(2024, 5, 1);
d2.Init(2024, 5, 5);
d1.Print();
d2.Print();
return 0;
}
- 对上述类有一个问题:
- 上面代码中的函数Init和Print是怎么知道操作的对象是d1,而不是d2的呢?
- C++中引入了this指针解决了这个问题,即:C++编译器给每个非静态的成员函数增加了一个隐藏的指针参数,让指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的访问,都是通过这个指针访问的。只不过对用户是隐藏起来的,用户不需要传递,编译器会自动完成操作。
📋8.2、this指针的特性
- this指针的类型:类类型* const,即,成员函数内不能给this指针赋值。
Date* const this
- 只能在类内使用。
- this指针本质成员函数的形参,但对象调用成员函数时,将对象的地址作为实参传递给this形参。所以对象内不会给this指针开辟空间。
#include<iostream>
using namespace std;
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
//语法上的转换 void Print() ==> void Print(Date* this)
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2;
d1.Init(2024, 5, 1);
d2.Init(2024, 5, 5);
d1.Print();//语法上的转换d1.Print(); ==> d1.Print(&d1);
d2.Print();//d2.Print(); ==> d2.Print(&d2);
return 0;
}
- this指针是成员函数第一个隐含的指针形参,由编译器通过寄存器自动传递,不需要用户传递。
- this的一些细则:
- this不能显示传实参和写形参。
- this可以在成员函数内显示写this。
至于为什么可以在成员函数里显示写this指针呢,到类和对象中篇会给大家讲到。