如图所示:我们在学习结构体是总是定义一个结构体对象,然后这个对象在结构体外部一个一个函数进行操作,面向着过程在实现我们的需求。但是这样子分步骤来实现需求总是显得比较麻烦,就像是手洗衣服一样,那么现实生活中有洗衣机,所以cpp引入了类这个概念,然后将过程集中到类里面,我们只需在类外面进行“洗衣服”这个操作,这样可以面向对象了,下面我们用一个栈的类来体现
// 栈类
class stack {
public:
// 栈的初始化
void init() {
_stackArray = nullptr;
_stackTop = _capacity = 0;
}
void destory() {
_stackArray = nullptr;
_stackTop = _capacity = 0;
}
void push(int value) {
// 扩容
if (_stackTop == _capacity) {
int newCapacity = _capacity == 0 ? 4: _capacity * 4 ;
int* tmp = (int*)realloc(_stackArray, sizeof(int) * newCapacity);
if (tmp == nullptr) {
perror("malloc fail");
return;
}
_stackArray = tmp;
_capacity = newCapacity;
}
// 栈顶插入
_stackArray[_stackTop] = value;
_stackTop++;
}
void pop() {
if (_stackTop == 0) {
cout << " 栈内没有元素可以出栈 " << endl;
return;
}
_stackTop--;
}
void printTop() {
assert(_stackTop!=0);
cout << _stackArray[_stackTop-1] << endl;
}
// 成员变量最好加前杠(利于成员方法区别参数),成员变量一般封装
private:
int* _stackArray;
int _capacity;
int _stackTop;
};
void test_1() {
// 实例化一个栈的对象
stack myStack ;
// 直接调用公共区的函数
myStack.init();
myStack.push(10);
myStack.printTop();
}
我们在void test_1()处直接定义了一个对象,然后开始使用类这个“洗衣机”来完成“洗衣服”,那下面正式开始类与对象的学习
类与对象
内容如下
- 封装
- 访问权限以及访问限定符
- 成员函数以及成员变量
- 类的大小
- this指针
封装
将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口和对象交互。
也就是说,我们通过类将数据进行封装,我们不能直接访问类的属性,只能通过调用类中的方法来实现对对象属性功能的访问。(这样做的好处是什么?可以提高代码的安全性,当程序很大的时候,一个程序员可能只负责某一个模块,程序员将自己所写的程序进行封装,然后只对主函数提供几个接口(主函数可以调用的方法),那么在调试的过程中,编程人员可以很快的找到代码错误的地方,提高了代码的可维护性)
实际上封装可以避免使用者在调用接口的时候不对成员变量有操作的机会,减少了代码被更改而出bug,一般用关键词 private,所以一般封装的是成员变量,以及部分成员函数,并且封装了成员函数也可以通过未封装的成员函数来打印, public 是公共的,未封装成员的关键字,这里我们可以看“栈类”那个代码的示例
访问权限以及访问限定符
成员函数与成员变量
一句话总结:成员变量和成员函数就是定义在类里面具有紧密关系的变量和函数
那么成员函数和成员变量实例化,在创造对象是空间是怎么分配的呢?
答案是:
1.不同对象的成员变量在不同的空间
2.不同对象的相同成员函数在同一块区域
类的大小
c++类的大小一般跟成员变量大小有关,与成员函数无关
但是与结构体一致遵守内存对齐原则
对于下面这行代码,sizeof(test) = 8,尽管int大小为4,char大小为1,但是由于内存对齐最后为8
class test{
int a;
char c;
};
加上了成员函数最后仍为8,因为成员函数不占大小
class test{
int a;
char c;
void func(){
//
}
};
对于没有成员函数,成员变量的空类大小为1,因为类这机制在为空的时候自动占位,以开辟空间
class test{
};
this指针
发现了一篇很好的博客那我就不总结了吧嘿嘿嘿