C中的封装
在C语言中采用struct声明结构体封装数据,再另外声明函数去描述基于这些数据的行为。再以指针的方式去传递参数给行为。
如:
typedef struct date{
int day;
float time;
}date;
void show(date *d )
{
printf("%d,\t,%f",d->day,d->time);
}
int main(){
date d;
d.day=6;
d.time=12.5;
show(&d);//注意这里是取地址,C语言没有引用
}
分析:这样的封装是不彻底并且不方便的。因为在任何时候都可以使用和改变数据,导致数据不安全。
Cpp中的封装
Cpp中采用了class以类的方式封装数据与行为并增加了权限控制,
特性:
1、权限控制
struct 中所有行为和属性都是默认为public的。C++中的class可以指定行为和属性的 访问方式,默认为 pirvate。参考另一篇博客class与struct的区别
访问属性 | 属性 | 对象内部 | 对象外部 |
---|---|---|---|
public | 公有 | 允许访问 | 允许访问 |
protected | 受保护 | 允许访问 | 不允许访问 |
private | 私有 | 允许访问 | 不允许访问 |
2、对内数据开放;
由上面的表就可以看出来了,成员函数即行为,可以访问任何类型的数据并且不需要传递参数。
3、逻辑抽象;
将基于数据的操作,封装成函数,对外提供接口
4、对外提供接口,屏蔽数据
外部不允许访问数据,只允许访问public下的成员。
构造函数与析构函数
构造函数
1、构造函数与类名相同,无返回值,生成对象时自动调用。
2、可以有参数,默认参数,支持重载。
特别的,无参数时,声明对象时,不要写括号,如:
class date{
public :
date(){
}
};
int main(){
//生成一个对象
date a();//错误,因为这样的声明与函数声明相同,编译器无法区分
date a;
}
3、如果程序员没有提供构造函数,系统则提供无参空构造函数
4、重载与默认参数不能同时存在如:你定义了一个无参构造函数,和带一个默认参数的构造函数,系统同样的不知道该调用哪一个构造函数生成对象。
析构函数
1、与类名相同,比构造函数多了“~”符号,用于对象销毁时的内存处理工作,(在对象销毁前调用)
如果是直接,date a
;程序运行结束则自动析构,
如果是动态申请,date *a=new date
,则必须使用delete a
才会调用析构函数。
2、如果没有提供析构函数,系统提供空析构函数
3、如果在类中申请了额外的空间,则先释放这部分空间,再释放对象空间。
4定义多个对象时,先定义的后析构,类似栈先进后出。
写在最后——class内存大小
类对象的大小为数据成员的最大数据成员的整数倍(字节对齐问题)。成员函数不占类对象空间。
构造函数与析构函数的调用并不是为了申请和释放对象本身的空间,而是处理 对象中可能申请的空间。