1. 结构体
Struct 名称{
类型名变量; //定义成员数据
成员函数;
};
与类相似,可以使用public,private,protected.默认public.
2. 共用体
Union 名称{
类型名变量1;
类型名变量2;
类型名变量3;
};
- 任何时刻,共用体只有一个成员起作用,且共用体所有成员共用一个存储空间,其大小由占用最大存储空间的成员决定.
- 不能对共用体变量直接输入输出.共用体类型成员可以是任意已定义类型.
3.枚举类型
enum 枚举类型名{枚举表};
例如:enum day{sun,mon,tue,wed,thu,fri,sat};
a. 枚举表中默认第一个元素为0,依次为1,2,3…特定值也可以在定义时显式指定其值,但是其余值保持默认值不变.
b. 枚举类型变量只有赋值和关系2种运算,且必须是同类型的枚举变量或者常量之间的运算.
4.类
Class 类名
{ public: 成员数据或成员函数的说明;//允许类内外函数访问该类内成员数据或调用该成员函数
Private(默认): 成员数据或成员函数的说明; //只允许类内的函数访问该类内成员数据或调用该成员函数
protected: 成员数据或成员函数的说明;// 允许类内或其子类的函数访问该成员数据或调用该成员函数
}
4.1.成员函数简介及其存储方式
成员函数必须在类体内原型声明,然后在类体外定义.或者直接在类体内定义
类体外定义成员函数: <inline> <返回类型> <类名>::<成员函数名>(参数表) <const>
1). ::作用域运算符,表明该函数属于该类.
2).类体外定义的内联函数,需关键字inline,类定义和函数定义须放同文件中,即:须在使用前定义,否则编译时内联函数无法插入调用处.
3).const表明改函数是否为常函数.常函数无法修改函数内任何数据类型.
类体内定义成员函数:可以直接按正常方式定义,不用::符.C++把类体内定义的函数默认为内联,省略关键字inline.
由于类只是个类型,因此在声明类时候,系统不分分配内存.在定义类的对象时候,系统给各个对象分配存储空间.,系统只给对象分配保存成员数据的存储空间,同类型对象共用函数代码存储区,采用this指针来区别不同对象的操作.
this指针简介:指向本类对象的指针,其值是当前被调用成员函数所在对象的起始地址.默认为:<类名> * const this=&对象
成员函数可直接调用该类成员数据,因为调用对象S1的成员函数时,系统把S1地址赋值给this指针,系统按照this指向找到S1的成员数据
如果一个函数会改变一个对象的状态,那它就应该作为这个对象的成员.
4.2构造函数
构造函数会在定义对象时候,根据给出的参数自动调用1次,给该对象初始化.
类体内定义: <类名>(形参表)
类体外定义:<类名>::<类名>(行参表)
注:构造函数与类型同名,无返回类型,可重载;要么使用无参构造函数和有参构造函数,要么使用全部默认参数的构造函数(使用全部默认参数构造函数后,不可再定义重载构造函数)
4.3析构函数
定义:<类名>::~类名() {…}
注:析构函数和类型同名,加字符~;没有参数及返回值;不可重载;在撤销对象时,系统自动调用析构函数;
正常情况下,系统遵从”先构造后析构,后构造先析构”原则,但对象不同作用域时,情况有所不同.
4.4常对象及常指针
new:动态建立对象内存,返回该对象地址.例: 指针=new 类名<参数>;
delete:释放有new建立的对象内存.例: delete 指针;
a.常成员数据:只能通过构造函数初始化列表进行初始化
b.常成员函数:只能引用本类成员数据,不可修改.const是该函数类型的一部分,因此声明和定义函数都要const关键字.
c.指向对象的常指针:<类名>* const <指针变量名>;指针指向的地址不可变.,但可改变其指向的值.
d.指向常对象的指针:const <类名>* <指针变量名>;
类型1 → 类型2
const类型变量 ↘→ const类型变量
非const类型变量 →非const类型变量即:非const类型变量不可调用const变量
通过类型1对类型2的使用,包括指针指向,函数形参的调用,引用等等,都遵从以上使用原则,因为const只具有”数据不可修改”这一性质,而非const具有”数据不可修改”和”数据可修改”二条性质. 使用类型2时需符合类型1的使用规范.
4.5静态成员数据和函数
a.静态成员数据是定义类时用static修饰成员数据.只属于类,不属于任何对象,单独开辟内存存放,不随任何对象的撤销而释放.其值对所有该类对象有效,任何该类对象都可以改变它,且只能在类体外初始化.可以用类名或对象名来引用.
b. 静态成员函数:不属于任何对象,无this指针,只能直接访问类中静态成员数据,可通过类名或对象名来调用.
注:静态成员数据和静态成员函数强调的是作用域时间,与访问权限无关.在类内声明static即可,类体外定义时无需加static
4.6 友元函数及友元类
类内声明友元函数:friend <类型> 函数名(参数列表)
友元函数是普通函数,并给该类成员函数,因此不具有this指针,但可以引用该类私有成员,可以说只是通过关键字friend在类体内声明某一普通函数,来使该函数具有对某类型的友元性质
友元类的所有成员函数都是该类的友元函数:类B内声明友元类:friend class A;将类A声明为类B的友元类.
4.7继承和派生类
声明派生类: class <派生类名>:<继承方式><基类名>,<继承方式><基类名>,<继承方式><基类名>…
{ <派生类新定义成员>; };
继承方式:
继承方式 | 基类特性 | 派生类特性 |
共有继承 | Public | Public |
Protected | Protected | |
Private | 不可访问 | |
私有继承 | Public | Private |
Protected | Private | |
Private | 不可访问 | |
保护继承 | Public | Protected |
Protected | Protected | |
Private | private |
派生类构造函数定义:
派生类构造函数名(参数表:包括基类构造函数所需参数,包含对象构造函数所需参数,派生类新增成员所需参数):基类构造函数名(参数表),...,对象构造函数名(参数表) {//新增数据初始化(不包括对象成员)}
派生类构造函数只在定义时需写出 : 后面的基类和包含对象的构造函数名及其参数,声明时不用写出.
派生类构造函数执行顺序:先基类构造函数,后派生类构造函数;调用基类构造函数顺序由声明派生类时基类出现顺序来执行.
派生类析构函数:通过调用派生类的析构函数来调用基类析构函数.先派生后基类,基类中成员由基类析构函数处理.
如果类型S是类型T的共有继承派生类,则S是T的子类型,S适应与类T,S具有T中的操作,此时对类T对象进行操作的函数也可以对类T的子类的对象进行操作.
通过类的继承来来纵向组织类,通过类的组合(包含某类的对象)来横向组织类.一个基类可以衍生多个派生类,一个派生类可以以不同方式继承多个基类
指向基类的指针,也可以指向派生类,基类的引用也可以用来引用派生类.通过这2个性质可以实现动态绑定:动态绑定函数(虚拟类)或者类型对象(基类或者派生类)
有时基类和子类有相同的F()函数,可以将此函数定义为虚拟函数(声明为virtual),此时程序将根据改函数的参数的实际类型来决定调用那个F(),基类中的,或者子类中的.如果基类中定义某函数为虚拟函数,则子类中的同名函数会继承虚拟性质,不用重复virtual关键字.
只有在以基类引用或指向基类的指针为参数调用虚拟函数时候,该引用或指针可能指向基类,也可能指向派生类,它运行时的选择特性才会有意义(动态绑定);
当函数参数为具体类型时候,在程序编译时候已经确定了参数类型.(静态绑定)