C++有三大特性:封装、继承和多态
一、什么是封装
隐藏对象的属性和实现细节,仅对外公开接口和对象来进行交互,将数据和操作数据的方法进行有机的结合
函数就是封装的一种形式,函数所执行的所有细节行为都被封装到函数这个实体中了,用户在外面都是看不到的,只能去调用这个函数,去完成一些操作
二、为了实现类的封装性,有以下几种访问限定符来辅助类:
1.公有(public)访问限定符
2.保护(protected)访问限定符
3.私有(private)访问限定符
三、访问限定符的属性
1.类中权限为public的成员变量以及成员函数可以在类外直接访问
2.类中权限为protected和private的成员变量以及成员函数不可以在类外直接访问(ps:类被继承时会有所不同)
3.访问限定符的作用域为当前访问限定符到下一个访问限定符
4.如果类中的成员变量以及成员函数没有定义访问权限,那默认为私有(private)
ps:
(1)类外指的是脱离了类的作用域
(2)访问限定符只在编译期间有用,当数据映射到内存之后,没有任何访问限定符的区别
四、如何在类外访问类中的私有成员变量
1.封装函数法
把被访问的成员变量封装到一个函数中,再把此函数的访问权限设置为公有(public)的,这样在类外访问此函数就可以完成对私有成员变量的访问了
2.指针法
因为变量在内存中是没有访问限定符的区别的,通过计算变量的偏移地址,可以得到要访问的私有成员
假如:要访问student类中的成员_grade,那计算出成员_grade相对于类起始位置的偏移量,这样就可以得到此成员了
3.添加一个友元类或者友元函数
假设A类或者函数Func()要访问B类中的私有成员变量,那把A类或者函数Func()设置为B类的友元类或者友元函数,这样就可以在A类中或者在函数Func()中访问B类的私有成员变量了
五、类的作用域
1.全局作用域
跟C语言中的一样,变量具有全局作用域的空间,与全局作用域对应的变量是全局变量
2.局部作用域
跟C中一样,局部变量所在的空间
3.名字空间域
此作用域是C++新引入的作用域,非常的灵活,可以用花括号括起来,以关键字namespace开头,如下:
namespace A
{
float a;
funtion()
{}
}
在此作用域中声明的成员(变量和函数)在此作用域外使用时,需要加上域操作符”::”,例如:A::a=3.0;
ps:名字空间域就相当于是一个全局域,只是在使用的时候,需要加域操作符
(1)在使用名字空间域,怎么样可以不加域操作符,可以直接使用?
使用关键字using
using指示符可以一次性的使名字空间中的所有成员可以直接使用,例如:using namesapce std;//std是名字空间的名字,C++库中的所有组件都在此作用域中,using使得此空间中的所有变量可以直接使用,不用加域操作符
(2)为什么需要名字空间域?
为了解决全局名字空间污染,即就是为了防止全局实体名与C++库中的声明的全局实体冲突
4.类域
类中成员所处的作用空间,成员包括成员变量和成员函数
类中的所有成员都必须在类的作用域中,但是在类中出现的变量,不一定是类的成员
(1)类域中的成员如何使用
a、在类中,可以直接使用,类的成员在类中具有全局作用域
b、在类外,定义成员时需要使用作用域解析符” :: “,指明此变量或者函数属于哪个类,而且在类的作用域外访问类的成员时,只能通过对象或者借助成员访问操作符.和->来访问类成员
六、类的实例化
1.定义:用类类型创建对象的过程称为实例化,如下:
class A
{};
int main()
{
A a;//类的实例化
retunr 0;
}
2.一个类可以实例化出很多个对象
3.空类的大小
include<iostream>
using namespace std;
class A
{
};
int main()
{
A a1,a2,a3;//用类A实例化了是哪个对象,分别是a1、a2和a3
cout << sizeof(A) << endl;//类A就是一个空类
system("pause");
return 0;
}
运行结果:
(1)空类的大小为什么是1字节,而不是0字节?
因为如果空类的大小是0时,会使得对象a1、a2和a3的地址相同
(2)空类的大小为什么是1字节,而不是2字节或者3字节?
空类的大小给1个字节,即区分类实例化的对象,又节省了空间,如果空类的大小给比1大的字节,会造成空间的浪费
ps:空类的大小是会因平台而发生变化的,VS下是1,LINUX下也是1,切记,不以平台为前提而计算空类的大小都是在耍流氓!!!
七、类与对象的区别
类是不占用存储空间的,只有当类实例化出对象,才会占用存储空间,即就是类实例化出的对象占用实际的物理空间,来存储类成员变量