我们都知道C++有三大特性:封装、继承、多态,之前我总结过继承的知识点,现在来总结一下封装的相关知识!
一、什么是封装?
- 封装:隐藏对象的属性和实现细节,仅对外公开接口和对象进行交互,将数据和操作数据的方法进行有机结合。
说明:
函数是封装的一种形式:函数所执行的细节行为被封装在函数本身这个更大的实体中,被封装的元素隐藏了它们的实现细节–可以调用一个函数但是不能够访问函数所执行的语句。
- 访问限定符
(1)public(共有)
(2)protected(保护)
(3)private(私有)
说明:
(1)public成员可以在类外直接访问。
(2)protected和private成员在类外(在此将这两种限定符都可以看成是私有的,在继承出区别)不能够访问。
(3)它们的作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。
(4)class的默认访问权限是private,而struct为public型(因为struct要兼容C)。C++常用的是class
(5)类外:即脱离了类的作用域或者说访问时不在类的成员函数中。
因此C++的封装和函数有一些不同,它能够更加灵活的满足不同对象调用的需求,因此封装相当于是class+访问限定符
注意:访问限定符本质上是给编译器使用的,数据放在内存中是没有任何限制的
来段代码看看:
class CDate
{p
ublic:
void SetDate(int iYear=1990, int iMonth = 1, int iDay = 1)
{
_iYear = iYear;
_iMonth = iMonth;
_iDay = iDay;
}
void PrintDate()
{
cout<<_iYear<< "-"<<_iMonth<<"-" <<_iDay<<endl;
}private:
int _iYear;
int _iMonth;
public:
int _iDay;
};
int main()
{
CDate d;
d.SetDate(2016, 3, 2);
d.PrintDate();
// d._iYear = 2016; // 私有成员变量不能再类外直接访问
// d._iMonth = 3;
d._iDay = 2;
return 0;
}
二、类的作用域
- 局部作用域
- 全局作用域
- 类作用域
- 名字空间作用域
(1) 在类体外定义成员,需要使用 :: 作用域解析符指明成员属于哪个类域。
(2) 在类的作用域外,只能够通过对象或指针借助成员访问操作符.和->来访问类成员,跟在访问操作符后面的名字必须在相关联类的作用域中。
(3)成员变量在类中具有全局作用域。
namespace NewSpace
{
int iValue = 10;
} i
nt iValue = 20;
class CTest
{public:
void FunTest(int iValue)
{
iValue = iValue;
}v
oid Print()
{
cout<<iValue<<endl;
}
private:
int iValue;
};
int main()
{
CTest test;
test.FunTest(30);
cout<<iValue<<endl;
cout<<NewSpace::iValue<<endl;
test.Print();
system( "pause");
return 0;
}
三、类的实例化
举一个例子我们来体会一下类的实例化的过程:
- 类–>实例化–>对象
- 图纸–>建造–>别墅
类是抽象的,只是限定了类中有哪些成员,定义了类并没有分配实际的内存来存储它。
CDate d; // 类实例化
//用类类型创建对象的过程
//一个类可以实例化出多个对象,实例化
四、类对象模型
- 类中的成员和对象在类中布局格式:
说明:
(1)可以用sizeof来求一个非空类的大小;
(2)空类的大小为一个字节,但是如果该空类变成非空类,例如类中有一个int,则该类的大小计算时,不在计算原来的1。
五、this指针
特性
(1)this指针的类型:类类型* const。
(2)this指针并不是对象本身的一部分,不影响sizeof的结果。
(3)this是一个指针,它时时刻刻指向对象的实例。
(4)this指针的作用域在类成员函数的内部(不严谨)。
(5)this指针是类成员函数的第一个默认隐含参数,编译器自动维护传递。
(6)只有类的非静态成员函数中才可以使用this指针,其它成员函数都不可以。_thiscall调用约定
(1)_thiscall只能够在类的成员函数上;
(2)参数从右向左压栈;
(3)如果参数个数确定,this指针通过ecx传给被调用者。如果参数不确定,this指针在所有参数被压栈后压入堆栈;
(4)参数个数不定的,调用者清理堆栈,否则函数自己清理堆栈。this指针是否为空?
void test(person* const this)
{}
void change(person* const this)
{
cout<<name<<endl;
}
当将空的this传给test函数时,test没有调用任何函数,因此执行此函数,没有报错;
当把空的this传给change函数时,通过this指针调用this->name,由于this是空的,因此会出错。
总结:
(1)NULL对象指针可以调用成员函数;
(2)通过对象调用成员函数,对象的指针会被传入函数中,指针名称为this;
(3)NULL对象指针调用成员函数时,只要不访问此对象的成员变量,则程序正常运行;
(4)NULL对象指针调用成员函数时,一旦访问此对象的成员变量,则程序崩溃。