类
2016-01-03 20:35
531 查看
类(class)
1.定义:类头 类体 数据成员 函数称为成员函数或方法
其中数据成员和成员函数统称为成员
成员的关键词为public(公有) private(私有) protected(保护)说明类的访问权限
在类的定义中 数据成员在声明的时候不能初始化
在类的定义中 定义的成员函数式内联函数 不加inline为隐式内联函数 反之为显式
2.类的使用:
1) 对象的声明:类名 对象列表名
Eg:CLOCK c1,c2;
2) 成员的使用:
对象名.数据成员 (访问数据成员)
对象名.成员函数名<实参列表>(访问成员函数 必须一一对应)
注意:
1) 通过.运算符只能访问public的成员
2) 对象一般不能直接输入 不能整体输出(运算符重载后 可以重新规定>>的含义)
3) 同类对象可以通过赋值运算符进行整体赋值
4) 可以定义对象数组 某个类型的指针 其相应的操作也可以实现 其格式为将数据类型改为类名
3.构造函数(进行赋值)
1)定义
Public:
类名 ()//默认构造函数
类名 (类名&c)//拷贝构造函数
类名 (形参列表)//其他构造函数 (也称带参数的构造函数)
函数重载:定义功能相同的函数 但是参数数据类型不同的函数 自需定义一次即可
凭借参数数据类型不同来分辨不同的函数 即函数重载
以上可以说明构造函数可以重载
构造函数没有返回值
2)构造函数的使用
构造函数在声明对象是不能直接调用 不能通过对象名.成员函数(实参)的方式调用
当声明对象只有对象名称时 系统默认调用构造函数
当声明的对象后加一对圆括号 圆括号内是另一个对象名 系统调用拷贝构造函数
当声明的对象后加一对圆括号 圆括号内提供若干实参时 根据函数重载的规则 调用相应的构造函数
3)构造函数的其他说明
1)即使没有任何参数 也应该有函数体 当一个类中没有定义任何构造函数时系统默认构造一个构造函数 当构造函数存在时便系统便不在构造
2)拷贝构造函数的参数是同类对象的引用 类的数据成员含有指针成员时 需要程序员自己定义拷贝构造函数来完成指针成员的定义
3)带参数的构造函数用具体的数值进行初始化
4.析构函数
1)定义:格式 ~类名
可以在类内定义 也可以在外定义 如果你没有定义 系统自动定义一个空的构造函
2)函数的调用时机
析构函数在对象撤销的时候进行调用 除了delete撤销动态申请的对象外
5.类的组合
1)概念:一个类中有其他类 这里的其他类称为内嵌对象 内嵌对象需要事先定义
2)组合类的成员可以通过.(点)运算符或者箭头运算符->进行访问 不过 可以有多级
3)内嵌对象的初始化;
形式
类名 ::类名(形参表0):内嵌对象1(形参表1),内嵌对象2(形参表2){
类的初始化
}
几点说明
1)内嵌对象1(形参表1),内嵌对象2(形参表2)为初始化列表 对内嵌对象进行初始化 效率比赋值语句高
2)对于基本数据成员也可以采用此方法 形如Point::Point(int a,int b):x(a),y(b);
3)构造函数的调用顺序 先调用内嵌函数的 在调用自己的
4)如果定义组合类对象时没有指定对象的初始值 降调用默认函数的构造函数
5)析构函数与构造函数执行顺序相反
6.对象与指针
1)指向对象的指针(对象的地址也可以用&取得 指向对象的指针存放了对象的初始位置)
1)定义:与基本类型相似 形式 类名 *对象指针名
2)使用:通过指向对象的指针 可以访问对象的成员 使用->箭头运算符 形式:指针->成员名
需要注意的是 访问的也只能是公有成员 凡是 对象.都可以拿指针->代替 *出现在指针之前代表对象本身
使用new运算符 也可以动态创建对象和对象数组 例如:Npoint *p=new Npoint[20]/创建动态对象数组
使用delete可以释放动态对象和动态数组 例如delete p[]//释放动态数组
2)指向成员的指针(对象中的成员也有地址 指针可以指向成员函数和公有数据成员
1)指向公有数据成员 和普通指针操作相似
2)指向成员函数的指针
1)声明指针变量
<数据类型> (类名::*指针变量名 参数表)
形如:void(Date::*funa)(int N); 最大的不同是指针前应加作用域
2)为函数指针赋值
指针变量名=类名::成员函数名;
形如:fun=Date::show;
3)使用成员函数针
(对象名.*指针变量名)(实参列表);
例如:(today.*funb)(5); 与普通指针不同的是还需要写上对象名 点号. 星号*;
3)this指针 在每个成员函数中都有一个名字为this的指向本类对象的指针
通过这个地址可以访问该对象的数据成员与成员函数
7.多文件结构 c++中允许有多个源文件 每个源程序文件被称为编译单元 可以分别单独编译
1)类的定义文件
可以保存在拓展名为.h的文件中 类的文件定义一般包括数据成员与成员函数声明 不包含成员函数的定义
2)类的实现文件
拓展名为.cpp在文件开头应包含#include .h文件
3)类的使用 将类的实现和类的定义放到同一个文件中 .cpp放到工程中 .h放到.cpp文件中
4)预编译处理
1)宏定义
#define 宏定义指令
不带参数的宏定义 例如#define PI 3.14 在替换时被称作宏替换或宏展开
带参数的宏定义 例如 #define len(a,b) sqrt(a*a+b*b)
注意 宏替换只是机械的替换 例如 #define K 3+5 替换语句为 6*K 结果为 6*3+5;
5)文件包含 #include <>或 #include””
6)条件编译 指令包括 #if #else #endif #ifdef #ifndef #undef
继承(派生类)
1.吸收基类成员
2.改造基类成员 (派生中成员函数可以改变 但是在实现函数功能时必须一致 即2)
1)改变基类成员的控制权限(即继承方式)
2)对基类成员函数或成员变量进行覆盖(即在派生类中定义一个和基类成员变量和成员函数同名的成员 如果是成员函数那么参数也要一致 否则为重载) 调用派生类时只能是派生类中定义的同名成员 这种方法叫做 同名覆盖 在派生类中调用成员只能访问到派生类的成员 如果调用基类成员应用显示调用 即基类名::成员;
3)添加新成员 派生类不会继承构造函数以及析构函数 所以要添加构造析构函数
公有继承:公有继承保持基类的公有成员和保护成员的原有访问属性 私有成员仍然为基类的私有成员 但是可以通过基类公有成员访问
私有继承:所有的基类成员都成为私有成员或不可直接访问的成员 基类的成员再也无法在新的派生类中直接发挥作用 所以很少采用私有继承
保护继承:直接派生和私有继承一致但是在接下来的继承就变得不一样了 保护继承有可能间接的访问到最初基类的成员对象
虚基类
假设有基类A 有两个派生类BC继承于A 但是D同时又是B和C的派生类 如果在派生时将B C同时放在D后会产生多份拷贝 因此产生歧义 需要消除
此时采用间接引用的方法
如果只想有一份拷贝 那么就需要虚函数了 然后就可以直接引用了
格式为 class 派生类名:virtual 继承方式 基类名;
多态性(统一接口 不同实现)
相关文章推荐
- JS 变量提升
- 看到的比较有意思的几个算法
- Java之String与CharSequence、StringBuffer与StringBuilder之间区别
- LeetCode-39-Combination Sum(DFS)-Medium
- C++ 知识点
- Android 开发之获取相册照片和获取拍照照片
- LeetCode :: Convert Sorted Array (link list) to Binary Search Tree [tree]
- replace与regexp_replace区别使用以及like与instr差异
- Onvif之设备发现
- touchesBegan不响应UIView问题
- 建造者模式
- 复杂操作数据存储结构
- Android View(三)-MeasureSpec详解
- 精益创业
- java配置环境变量
- Develop--Training(六)Getting Started--Working with System Permissions
- 高度自律是怎样一种人生体验(二)
- USACO rockers
- BZOJ-1305 dance跳舞 建图+最大流+二分判定
- poj 1064 高精度 二分