西南交通大学 姜自强 完成时间:2018.01.25
一:从 c 到 c++之非面向对象的扩充
1)<<预定义的插入运算符
>>预定义的提取流运算符
输出流:
输入流:
注明:在 6.0 以上的版本中,使用标准 C++头文件,#include
cout<<表达式<<表达式……
cin>>表达式>>表达式……
using namespace
2)如果一个函数中有多个默认参数,则默认参数应从右至左逐个定义。调用函数时,默认参
数可以省略不填。比如: int Product(int a,int b ,int c=10); 调用: Product(m,n);
3)内联函数:inline int Max(int x,int y) { 。。。}
注意:1、内联函数体内不能有复杂的结构控制语句,如循环语句、 switch、递归,否则
内联函数将和普通函数一样地被调用。2、内联函数中不能定义数组。3、内联函数的定义
必须出现在第一次调用前。4、内联函数的函数体不宜过大。5、类体中自动内联,不用
inline.
4)函数重载:函数名相同,但形参表不同的函数,此为函数重载。函数重载的目的:执行相
同的一般性动作。函数调用时,系统依据实参的个数、类型、或顺序确定所调用的函数。所以,
形参的个数、类型或顺序至少应该有一个不同。
下列是函数重载容易出错的地方:
a. 只有函数返回类型不同时,编译器会报错。
b. 函数存在默认参数(缺省参数)的情况:
调用时,会出问题,如:min(5,10); 会不知道调用谁。
c. typedef 为现有的数据类型提供了一个替换名,它并没有创建一个新类型。
5)函数模板:建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来
代表。 注意:它只适用于函数的参数个数相同而类型不同,且函数体相同的情况,如果参数
的个数不同,则不能用函数模板。函数模板生成的函数称为:模板函数。
定义:template 或 template 或 template
1 / 17
西南交通大学 姜自强 完成时间:2018.01.25
6)常量:
#define MAX 100 // C 语言的宏常量
const int MAX = 100; // C++ 语言的 const 常量
const float PI = 3.14159; // C++ 语言的 const 常量
•注意:const 与#define 的比较:在使用宏( #define)定义符号常量时不具备数据类型,
因此在编译中无法知道因类型而引起的错误。
错误 1:常量不能被赋值.。。错误 2:常量必须在定义的同时进行初始化
const 与指针配合使用,衍生出 3 种不同的用法:
a. 指向常量的指针:const int *p; int a;
b. 指针常量:int a;
c. 指向常量的指针常量:int b;
注意:字符指针。。。。char *pc = "a character array";。。。。
int * const p=&a;//*p 可变,p 不可变。必须先初始化。
const int *const p=&b;//*p 和 p 都不可变。
p=&a;//*p 不可变,p 可变。
7)引用及声明方法:引用就是给某个已知对象取一个别名。由于指针的不安全性,引用的目
的就是为了减少指针的使用。
int m;
int &rm = m;// 引用本身没有值和地址值,引用的地址值是
声明方法:
它被绑定的对象的地址值,它的值也是被绑定对象的值。独立引用必须在它被声明时加以
初始化。
在 c 语言当中:传值调用、传址调用。在 c++中还支持引用调用方法(按引用传递)。
引用特点总结:
1)&在此不表示求地址运算,而是标识在此声明一引用;
2)对引用求地址就是对目标对象求地址;
3)引用本身不占用存储单元;
4)在引用的使用中,单纯给某个对象取个别名无甚意义。使用引用的目的在于函数参数
传递过程中解决类对象的传递效率问题。
8)字符串类与字符串变量:
#include // 注意头文件名不是 string.h
字符串数组:string name[ 5] ; //定义一个字符串数组,它包含 5 个字符串元素
注意:每一个字符串元素 name[i]中只包含字符串本身的字符而不包括‘\0’。
2 / 17
西南交通大学 姜自强 完成时间:2018.01.25
9)自由存储:new 和 delete
int *ptr = new int(100);// 分配单个。100 是初始值。
delete ptr; ptr=NULL;
int * parray = new int[size]; // 数组。
delete [] parray; parray=NULL;// 数组。
// 释放单个。
指针悬挂问题:野指针(无效指针)
解决方法:指向 NULL
3 / 17
西南交通大学 姜自强 完成时间:2018.01.25
二:类和对象初步认识
1)类的定义:
分号不能省略。
成员的默认访问权限是私
有(private)的。
public 和 private 在类中
出现的顺序没有关系。
在类体外定义成员函数时,
需有作用域运算符::。
2)类的所有对象共享成员函数(方法),但每个对象拥有各自的成员数据(除静态数据成员)。
3)this 指针:该指针是系统创建的,用它来指向正在被某个成员函数所操作的对象,它的值
是当前被调用的成员函数所在的对象的起始地址。
Eg: reScore.SetScore(90,100,95); 此时 : this 指向 reScore 首地址.
4)当使用指针变量访问类的成员时,必须先使指针变量指向该类的某个对象。
5)在类中不能对所定义的数据成员(除静态常量成员)进行初始化;静态常量成员只能定义时
初始化。Eg:static
months
12;
const
int
=
6)构造函数:专门对对象进行初始
化;在对象创建时初始化。
默认构造函数是指不需要用户指定
实参就能够被调用的构造函数。
一个类只能有一个默认构造函数。
三种默认构造函数:
7)拷贝构造函数:• 拷贝构造函数定义的一般形式:类名( const 类名 &对象)
• 调用时的一般形式:类名 对象 2(对象 1);
拷贝构造函数,只拷贝需要的成员数据,像姓名、编号这些值不拷贝。
4 / 17
西南交通大学 姜自强 完成时间:2018.01.25
Eg:定义: CStuScore(const CStuScore & score)
{
for(int i=0;i<3;i++) { m_fScore[i]=score.m_fScore[i];} }
调用:CStuScore Score2(Score1);// Score1 为已初始化的对象。
8)析构函数:
析构函数在以下情况下自动调用:
(1) 静态存储类对象,析构函数在
程序结束时自动调用;
(2) 当对象定义在一个函数体中,
该函数调用结束时,自动调用;
(3) 用 new 为对象分配动态内存后,当使用 delete 释放对象时,析构函数被自动调用。
9)对象数组:定义一般格式:CStuScore Score[100]; //调用默认构造函数
10)动态分配对象:可对照“一:9)”。
CScore *pScore=new CScore; 或 CScore *pScore=new CScore("张三", "21020502");
创建堆对象时,先分配空间,然后调用对象的构造函数;
删除堆对象时,先调用对象的析构函数,然后回收空间。
11)动态分配对象数组:一样的原理,可对照“一:9)”。将数据类型换成类名即可。
三:类和对象进一步认知---1
5 / 17
西南交通大学 姜自强 完成时间:2018.01.25
1)静态数据成员:
a. 静态数据成员是同一个类中所有对象共享的成员,而不是某一对象的成员。
b. 静态数据成员初始化须在类的外部进行。Eg:
注意: 静态常量成员只能定义时初始化。Eg:static
const
int months
=
12;
2)静态成员函数:无须产生类的对象即可访问静态数据,也是所有对象共享的。
其声明、定义的方法与普通成员函数一致,只是在前面加关键字“static”.
注意:静态成员函数不单独属于某个对象,因此若要在静态成员函数中访问非 static 成
员时,必须明确指出该静态成员函数在哪个对象上操作,不能对类中的非静态成员进行默
认访问(cout<
西南交通大学 姜自强 完成时间:2018.01.25
4)友元类:让一个类可以存取另一个类的私有成员。
一般用第一种声明。
类 B 是类 A 的友元类,因此,类 B 的所
有成员函数中均可访问类 A 的任何成员。
友元关系不具有传递性。即如果类 B 是类 A
的友元类,类 C 是类 B 的友元类,并不隐含
类 C 是类 A 的友元类。
5)共享数据的保护:使数据能在一定范围内共享,又要保证它不被任意修改,使用 const。
常对象:在定义对象时指定对象为常对象。常对象必须要有初值,如:
const CPoint p1(1,2); 或 CPoint const p1(1,2); //定义常对象 p1。
企图调用常对象 p1 中的非 const 型成员函数为非法操作。 如: p1. Getx( ) ; //非法
这是为了防止非 const 函数会修改常对象中数据成员的值。
所以,引用常对象的数据成员只能将该成员函数声明为 const。如 double Getx( ) const;
常成员函数只可以引用对象中的数据成员,但不能修改。常成员函数中不能调用非常成员
函数。
注意:构造和析构是例外,即使构造和析构不是常成员函数,常对象也可以调用它们。
常成员:
(t)即为
初始值,常
量 初 始 化
后 就 不 再
改变,所以
后 面 无 需
再初始化。
6)类模板:对照“一:5)函数模板”看。
类模板的一般定义:
Class 与 Typename 可
替换使用。
调用时(定义对象时),
用
7 / 17
西南交通大学 姜自强 完成时间:2018.01.25
四:类和对象的进一步认识:继承和派生---2
1)继承:代码的可重用与扩展性
新类包含了已有类的所有成员,并增加了
自己的成员,这种现象称为继承。
单重继承:派生类只有一个直接基类。
多重继承:派生类有多个直接基类。
2)派生类定义格式:以单重继承的派生类为例:
class<派生类名>: <继承方式> <基类名>
<派生类新增成员>
};
表 1:基类成员在派生类中的访问权限
公用继承方式
不可访问
公用
保护
私有继承方式
不可访问
私有
私有
基类中成员
私有成员
公有成员
保护成员
8 / 17
保护继承方式
不可访问
保护
保护
总结: 在派生类中,基
类私有成员不可访问,
不管做什么操作,都不
可访问。
公有继承不变,私
有继承变私有,保护继
承变保护。
在派生类中定义一
个接口函数,该接口函
数在类中调用基类成员
函数。比如:SetData();
这个基类函数,在派生
类中定义一个成员函数
调用它。再在类体外调
用这个接口函数,即可
访问 SetData()。