权限关键字
- private:代表此区块属于私有成员,具有最高的保护级别。也就是此区块内的成员只可被对象的成员函数所存取,在类中的默认存取类型为私有成员,即使不加上关键字private也无妨。
- protected:代表此区块属于保护成员,具有第二高的保护级别。外界无法存取声明在其后的成员,主要让继承此类的新类能定义该成员的存取权限,也就是专为继承关系量身定做的一种存取模式。
- public:代表此区块属于公有成员,完全不限制外界对声明在其后的成员的存取,此存取权限具有最低保护级别。此区块内的成员是类提供给用户的接口,可以被其他对象或外部程序调用与存取。通常为了实现数据隐藏的目的,只会将成员函数声明为public存取类型。
构造函数与析构函数
- 类的构造函数(constructor)可以用于对象初始化的工作,也就是如果在声明对象后希望能设置对象中数据成员的初值,可以使用构造函数来声明。
- 析构函数(destructor)用于在对象生命周期结束时释放对象所占用的内存空间。
构造函数
- 名称与类相同,没有返回值,支持重载
- 默认存在
析构函数
当对象被创建时,会在构造函数内动态分配若干内存空间,当程序结束或对象被释放时,该动态分配所产生的内存空间并不会自动释放,这时必须经由析构函数来执行内存释放的操作。
- 名称与类名称相同,在前面加上“~”符号,没有任何参数
- 不可以重载
- 当对象的生命期结束时或是我们以delete语句将new语句分配的对象释放时,编译程序就会自动调用析构函数。
对象数组与友元关系
对象数组
声明类的对象数组和声明一般数组方式相同
类名 对象组名[大小];
友元函数
友元函数可以直接使用类的任何数据与函数
friend 函数类型 函数名(参数);
友元类
友元类可以直接存取该类中设为private或protected的数据成员
class A{
friend class B;
};
class B{
}
this指针与静态数据成员
this指针
- 当创建对象后,对象会自动创建属于它自己的指针,即this指针
- 这个指针指向内存中存储该对象的地址,通过它可以存取对象的数据成员及成员函数。
- this指针的使用方式与一般指针相同。
- this指针代表了“当前这个对象”的指针,通过this指针可以存取到该类的数据成员和成员函数
静态数据成员
- 当类中的数据成员被声明成静态类型后,该静态数据成员的值将会保留下来,直到程序结束或下一次该数据成员的值要被改变时
- 要将类中的数据成员或成员函数声明成静态,只要在数据成员或成员函数前面加static即可
- 静态数据成员必须在类外部设置初值
嵌套类
嵌套类是定义在某个类内部的类。如果一个类的内部包含另外一个类的定义就称为嵌套类,
运算符重载
在C++中,运算符一种函数,可以借助重载的特性为该运算符定义不同的运算功能。
返回数据类型 operator 运算符符号(数据)
运算符重载并不会产生新的运算符,它只是将原有的运算符功能加以扩充。
继承关系
在继承之前,原先已创建好的类被称为“基类”(base class),而经由继承所产生的新类就被称为“派生类”(derived class)。通常会将基类称为父类,而派生类称为子类
- 在public继承声明之下,派生类可完全继承基类中的public和protected数据成员,并供成员函数直接存取。
- 基类中的private数据成员则被隐藏,无法直接存取。必须依靠基类的public和protected成员函数来执行间接存取的操作。
- 基类中的public数据成员可以被程序中任何类的所有函数来存取,而非派生类的成员函数则无法直接存取基类的protected和private数据成员,必须通过public成员函数间接存取。
单一继承
class A:public B{
}
- 当存取设置字符声明为public时派生类所继承而来的类成员(数据成员与成员函数)存取设置保持不变。
- 当派生类以protected声明继承基类时,继承而来的所有成员除了private类型继承之后仍是private类型之外,protected和public类型都会变成protected类型的成员。另外,派生类内的其他成员函数可以直接存取基类中位于protected与public存取区块内的成员,但是不可以存取基类内位于private存取区块内的成员。其继承后的存取设置会将原本是public的类成员改为protected
- 当派生类以private声明继承基类时,基类中的所有数据成员与函数会存储到派生类的private区块之中。与protected继承声明一样,非派生类的外部成员无法使用派生类的对象对基类进行调用或存取的操作,必须通过派生类的public成员函数来间接存取。在继承后,类成员的存取设置将会全部改为private
多重继承
一种直接继承的类型直接继承了两个或多个基类
class A:public B,public C{
}
派生类的构造函数与析构函数
在单一继承中创建构造函数与析构函数的顺序是:
- 先调用基类的构造函数,再调用派生类的构造函数。
- 当程序运行结束之后会先调用派生类的析构函数再调用基类的析构函数。
多重继承也和单一继承一样,在创建派生类时从基类中先调用构造函数再调用派生类1、派生类2等构造函数。当程序运行结束之后会先调用派生类2、派生类1的析构函数,再调用基类的析构函数
多态与虚拟函数
一般在程序中常常会在基类或是派生类中声明相同名称但功能不同的public成员函数。这时可以把这些函数称作同名异式或是多态(polymorphism)
虚拟函数(Virtual Function)就是多态的实现,使得我们能够调用相同的函数却执行不同的运算,因为这个成员函数所属的类实例可以被动态链接,而这些派生类又具有相同的基类。
virtual void A(int a);
一旦将函数声明为虚拟函数,编译程序就会给予这些函数不同的指针,在执行时则根据这些指针来存取适当的函数。所以当您要声明对象时,必须同时声明指针变量。
纯虚拟函数
virtual void A(int a)=0;
纯虚拟函数最主要的功能是在起始声明时并未加以定义该虚拟函数的本质而形成一种被保留的函数接口(interface)。这种方式造成日后声明的各个派生类可以直接使用该函数并加以定义、执行。
抽象基类
纯虚拟函数无法在单一类或是派生类中声明,只能存在于拥有继承关系的基类中,这种基类称为“抽象基类”(abstract class)。抽象基类包含了最少一个或多个纯虚拟函数,所以当派生类继承了抽象基类之后,必须在派生类中“重新定义”(override,或者覆盖)及“实现”(implement)所继承的纯虚拟函数。