过程和对象
C语言面向过程设计,c++面向对象设计,
举例:洗衣服
C语言:放衣服,放洗衣粉,启动洗衣机,脱水,拿出来晾干。
而c++关注对象,一共四个对象,人,衣服,洗衣粉,洗衣机。
这个过程是4个对象交互完成的,人不需要关注洗衣机如何工作洗衣服的,
类的引入,
C语言中结构体中只能定义变量,c++中可以定义变量和函数,如C语言实现的栈只能定义变量,而c++代码如下:
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef int DateType;
struct pll {
void StackInit(int capacity = 4)
{
_a = (DateType*)malloc(sizeof(DateType) * capacity);
if (_a == NULL)
{
perror("malloc fail");
return;
}
_capacity = capacity;
_size = 0;
}
void StackPush(int x)
{
if (_size == _capacity)
{
DateType* tmp = (DateType*)realloc(_a,sizeof(DateType) * _capacity * 2);
if (tmp == NULL)
{
perror("fail realloc");
return;
}
_a = tmp;
_capacity *= 2;
}
_a[_size++] = x;
}
int Top()
{
return _a[_size-1];
}
void Destroy()
{
if(_a)
free(_a);
_a = nullptr;
_capacity = 0;
_size = 0;
}
DateType* _a;
int _capacity;
int _size;
};
int main()
{
pll st;
st.StackInit();
st.StackPush(2);
st.StackPush(5);
st.StackPush(6);
st.StackPush(7);
st.StackPush(4);
cout << st.Top() << endl;
st.Destroy();
return 0;
}
4
注意,c++结构体中,定义的变量无先后顺序,无需注意定义变量的位置,所以结尾定义的_capacity等,开头的函数也能用。
🚩 并且在c++中,我们用class来代替struct
类的定义
class stu
{
public:
void test(int age=4)
{
_age=age;
cout << _sex << _age << endl;
}
public:
char _sex;
int _age;
private:
string _birthday;
};
为了防止类中函数参数也有sex,age这种,我们类中定义变量都是前面加_,方便与函数参数区分。
类的访问限定符及封装
类的访问限定符
🚩 c++实现封装的方式:用类将对象的属性和方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部用户使用。
访问限定符说明:
1, public在类外可以被直接访问。
2, protected和private在类外不能被直接访问。
3,访问权限从类的访问限定符出现位置开始,持续到下一个类的访问限定符的出现,
4,如果后面没有类的访问限定符就持续 }即类的结束,
5, class的默认访问权限是private,struct默认访问权限是public(因为要兼容c语言)。
class和struct区别?
:c++兼容C语言,所以struct和class都可以定义结构体,还可以都定义类,区别是class默认访问权限private,struct访问权限public。
封装
在类和对象阶段,主要研究类和对象的封装,那么什么是封装?
🚩封装:通过类的方式将数据和操作数据结合起来,隐藏对象的属性和实现细节,仅对外公开接口和对象进行交互,
封装本质上是一种管理,方便用户更容易操作类。例如电脑对外公开键盘,鼠标,显示屏,方便用户操作,但计算机真正工作是cpu,显卡,内存等硬件。
在c++,通过类对数据和操作数据有机结合起来,通过访问限定符隐藏对象内部实现细节,决定是否对外公开接口。
类的实例化
#include <iostream>
#include <string>
using namespace std;
class stu
{
public:
void test()
{
cout << _sex << _age << endl;
}
public:
char _sex;
int _age;
private:
string _birthday;
};
int main()
{
stu st;
return 0;
}
和结构体用法一样,用类创建实例对象就叫类实例化,一个类可以有多个实例化对象。
创建出的类就相当于建房子的一张图纸,没有分配实际的物理空间,创建实例对象的过程,就是拿着图纸建房子,分配了实际物理内存空间,。
类大小
#include <iostream>
using namespace std;
class cs1
{
public:
void test1()
{
int a;
}
};
class cs2
{
public:
void test2();
private:
long long a;
int b;
char c;
};
class cs3
{
};
int main()
{
cout << sizeof(cs1) << endl;
cout << sizeof(cs2) << endl;
cout << sizeof(cs3) << endl;
return 0;
}
1
16
1
类大小计算,里面函数不占字节,函数放在公共代码区只保存一次,多个实例化对象只需要保存各自的成员变量,成员变量需要内存对齐
编译器给空类一个字节,方便辨识
内存对齐规则:
1,第一个成员在结构体偏移量0位置处。
2,接下来的成员变量大小对齐在对齐数的整数倍地址,总大小是对齐数的整数倍
3,对齐数:编译器默认大小 和 该类最大类型的大小,vs默认8
这里该类对齐数8,因为long long字节占8,排0-7,int从8开始排8-11,char12,总共13字节,但补充13-15,总共16字节
4,如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍
this指针
#include <stdio.h>
using namespace std;
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;
d1.Init(2020,2,12);
Date d2;
d2.Init(2021, 3, 14);
return 0;
}
我们面临一个问题,d1,d2初始化时怎么确定是哪个_year,
所以引入了this指针:c++给每个非静态函数引入了this指针,this指向当前运行函数,函数内对成员变量的操作都是通过this指针访问完成的。只不过所有操作对用户是透明的,即用户不需要传递,编译器自动完成了。
this特性
1,this类型 *const,即不能改变 this指向,
2,this指针只能在自己本身函数使用
3,this指针是成员函数形参,函数调用将实参传给形参,所以类中不存储this
4,this指针是隐藏的指针,编译器通过ecx寄存器自动传递,不需要用户动手