1.类
1.1类的定义
class Student
{
int add(int a, int b)
{
return a + b;
}
char _name[20];
int _age;
char _sex[5];
};
如上面代码所示类的定义与C语言中结构体的定义非常的相似,C++中为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前⾯或者后⾯加_或者m 开头,注意C++中这个并不是强制的。
类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的⽅法或 者成员函数,这些成员默认是私有的,外部不能直接访问,如下图所示,可以按需求直接在类里面添加访问权限。
1.2访问限定符
访问限定符分为三种,在类中默认为private,public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访 问,protected和private是⼀样的,还需要注意的是访问权限作⽤域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为⽌,如果后⾯没有 访问限定符,作⽤域就到}即类结束。
1.3类域
类定义了⼀个新的作⽤域,类的所有成员都在类的作⽤域中,在类体外定义成员时,需要使⽤::作 ⽤域操作符指明成员属于哪个类域。
下⾯程序中Init如果不指定类域Stack,那么编译器就把Init当成全局函数,那么编译时,找不到array等成员的声明或者定义在哪⾥,就会报错。指定类域Stack,就是知道Init是成员函数,当前域找不到的array等成员,就会到类域中去查找。
#include<iostream>
using namespace std;
class Stack
{
public:
// 成员函数
void Init(int n = 4);
private:
// 成员变量
int* array;
size_t capacity;
size_t top;
};
// 声明和定义分离,需要指定类域
void Stack::Init(int n)
{
array = (int*)malloc(sizeof(int) * n);
if (nullptr == array)
{
perror("malloc申请空间失败");
return;
}
capacity = n;
top = 0;
}
int main()
{
Stack st;
st.Init();
return 0;
}
2.实例化
2.1实例化理解
在我的理解中实例化就类似于拿着别墅图纸去造房子,房子就是根据图纸制作出来的,一张图纸也可以制作很多房子,对应着我们的一个类也可以实例化多个对象。
2.2对象的大小
计算对象的大小跟计算结构体的大小是一样的,这里需要注意的是函数指针是不需要存储的,函数指针是⼀个地址,调⽤函数被编译成汇编指令[call 地址],其实编译器在编译链接时,就要找到函数的地址。
3.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:
//如果不写访问权限默认为prvite
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2;
d1.Init(2025, 5, 5);
d1.print();
d1.Init(2025, 5, 6);
d1.print();
return 0;
}
在什么代码中,可以看到我们创建了两个Date对象,当d1调⽤Init和 Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?
这是因为编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this 指针。⽐如Date类的Init的真实原型为, void Init(Date* const this, int year, int month, int day)。
实际上Init函数里面是这样的
void Init(int year, int month, int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
接下来来看一道题
this指针存在内存哪个区域的(A)
A. 栈 B.堆 C.静态区 D.常量区 E.对象⾥⾯
栈(A):函数的参数(包括隐式参数
this
)在调用时会被压入栈中。因此,this
作为参数,其本身存储在栈区。堆(B):仅当对象通过
new
创建时存在,但this
是参数,与对象存储位置无关。静态区(C)、常量区(D):存储全局/静态变量或常量,与函数参数无关。
对象内部(E):对象存储成员变量,不存储
this
指针。