1. C++和C语言最大的区别
以洗衣服为例,
C语言是手洗,你需要对每一个过程非常的清楚,一步一步都需要自己亲自去完成,
而C++更像是机洗,整个过程划分为人、衣服、洗衣粉、洗衣机四个对象的交互过程, 而人是不需要知道洗衣机是如何把衣服洗干净的。
也就是所谓的面向过程和面向对象的区别。
2. 什么是类
C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。
类其实有点类似结构体,只不过在C++中更加常用。
【关键字】class
【定义方式】类似结构体
class className
{
// 类体:由成员函数和成员变量组成
}; // 注意后面的分号
1)声明和定义均在类体中
你可能会好奇,为什么成员变量前面要加个下划线?
其实是为了和之后传进来的形参作区分
像Init函数中出现了成员变量和形参同在一个函数的情况,如果用一个下划线作区分就很容易辨别了
2)类声明放在.h文件中,定义放在.cpp文件中(常用)
PS:“ :: ”是类作用限定符,在类体外定义成员时用来指明属于哪个类域
3. 类访问限定符及封装
在使用计算机的时候,我们不需要关心内部的核心固件,只需要知道键盘鼠标怎么用即可。同理,在 C++ 中,通过类访问限定符来进行权限的管理,控制那些方法可供外部使用,也就是所谓的封装。
类访问限定符分为以下三类:
【说明】
1. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止,如果后面没有访问限定符,作用域就到类结束。
2. class的默认访问权限为private,struct为public (因为struct要兼容C)
3. 一般来说,成员变量用private,成员函数用public
4. 类的实例化
【不好理解的概念】类只是对一类对象进行描述,而对象是一个具体的类。
以学生信息为例,类里面包括成员属性和成员方法,学生类里面包括学生的姓名、班别、性别(成员属性),学生交作业、参加考试(成员方法);
而学生张三、李四、王五(对象),就是属于学生类的对象
5. 类对象的存储方式
每个对象的成员变量不一样,但是调用的都是同一份函数
所以为了节约空间,每个对象只保存成员变量,而成员函数保存在公共代码区
【小练习】
判断这三个类的大小是多少?
class A1 {
public:
void f1(){}
private:
int _a;
};
class A2 {
public:
void f2() {}
};
class A3
{};
答案:4,1,1
A1:有成员变量,就按照内存对齐的规则进行计算;
A2:没有成员变量,成员函数在公共代码区,不占内存
A3:空类,默认 1 字节,用来表示对象存在过,标识对象实例化
如果不熟悉内存规则的小伙伴可以看看这篇文章:链接
6. this指针
问题引入:既然不同对象的成员函数在同一个空间,那该如何区分函数内的成员变量属于哪个对象?
this指针就是解决这个问题的,它隐含在函数的参数中,传过去的是该对象的指针,不用显式写(显式写会报错),也不用传参,编译器通过寄存器ecx自动会传,此处只是为了说明。
注意:this 指针是 const 类,不可以修改
【面试题扩展】
1. this指针存在哪里?
它是形参,存在栈中,有的编译器会进行优化,存储在寄存器中
2. this指针能不能为空?
这个问题需要分情况讨论,见下面的分析
例子如下,当 A 类中的成员函数没有调用成员变量时,正常运行。因为成员函数存在公共代码区,如果没有调用成员变量,就不需要到对象的空间里面去获取成员变量的数据,所以此处并不会对空指针进行解引用。
class A
{
public:
void Print()
{
cout << "Print()" << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();
return 0;
}
而如果把 A 类改成如下,就会发生程序崩溃,也就是对空指针进行了解引用操作。
注意空指针是不会在编译时报错的,而是在运行时会崩溃
class A
{
public:
void Print()
{
cout << _a << endl;
}
private:
int _a;
};
7. C和C++再对比
在我们实现 Stack 的时候,C语言需要每次都传 Stack* 参数,而C++里有 this 指针会让编译器自动调用,减少了出错。且C++中有封装,设置不同方法不同权限。
C语言弊端:结构体中只能定义存放数据,操作数据的方法不能放在结构体中,即数据和操作数据的方式是分离开的,而且实现上相当复杂一点,涉及到大量指针操作,稍不注意可能就会出错。