第十二章 C与 C++
第十二章 C与 C++
12.1 C转入 C++
12.2 C转入 C++的一些与类无关的 新特性
12.3 C++的核心新特性 ——
12.4 面向对象程序设计
第十二章 C与 C++
12.1 C转入 C++时不需改变的内容
(1) 各种数据类型变量的定义与使用, 函数, 数组,
指针, 文件等基本知识 。
(2) 许多有效的算法 。
(3) 程序的基本调试思想方法 。
(4) 程序设计中的自顶向下的总体思想,
(5) 程序段中具体的最小模块仍然由顺序,分支,循环
三种基本模块组成。
第十二章 C与 C++
12.2 C转入 C++的一些与类无关的新特性
12.2.1 C转入 C++时需改变的内容
1,C++中不能再作为标识符的关键字
2,函数声明
3,
第十二章 C与 C++
12.2.2 C++中独有的与类无关的部分新特性
1,局部变量说明语句的位置
如,void main()
{ …… /* 程序的其它部分 (包括执行语句 ) */
int count=0; // 变量 count
while(++count<=100) // 变量 count
{……}
…… /* 后续程序 */
}
第十二章 C与 C++
2,
C++中可以使用两种注释符 (如上例 ),比 C多一种注
释符, //”,其功能是其后至行末为注释部分 。 程序中
可灵活选用 。
第十二章 C与 C++
3,范围分解符,,
C中, 当全局变量和某函数内的局部变量同名时, 该
函数对全局变量起屏蔽作用, 即在该函数内无法访问此全
局变量, 而在 C++中, 只要在其前使用范围分解符即可访
问同名的全局变量 。 例如,
float n;
void main()
{int n;
n=5; // 给局部变量 n
,,n=5.53; // 给全局变量 n
……
}
第十二章 C与 C++
4,
内联函数的特性类似于宏 。
C中, 在定义了宏 # define ABS(n)((n)<0?-(n),(n)) 之
后, 程序每调用一次宏 ABS,替换宏名的字符串就展开并
插入在调用处一次 。 C中的函数调用就不是这种展开方式,
而是程序转入子函数执行, 执行完后再返回主调函数, 每个
函数只有一段代码 。 在 C++中, 可以定义类似于宏的内联函
数, 关键字是 inline,如定义求绝对值的内联函数如下,
inline int Abs(int n)
{ return n<0?-n,n; }
第十二章 C与 C++
5,
C++中可以在同一程序中多次定义同名函数, 只要各
函数间的参数个数或类型不同, 例如,
int Abs(int n)
{ return n<0?-n,n; }
float Abs(float n)
{ return n<0?-n,n; }
第十二章 C与 C++
在同一范围内定义同名函数称为重载函数 。 编译器根据函数
调用时具体的实参的个数和类型自动调用匹配的重载函数版本 。
例如,
int Abs(int n);
float Abs(float n);
void main()
{int i;
float f;
i=Abs(5); //
f=Abs(-2.5); //
……
}
第十二章 C与 C++
6,new和 delete操作符
以下为动态开辟内存块的例子,
struct node
{ char *name;
int salary;
node *next;
}
char *pchar; // 定义三种类型的指针变量
int *pint;
struct node *pnode;
第十二章 C与 C++
pchar=new char; //
pint= new int;
pnode=new node;
*pchar=′a′; //
*pint=6;
pnode->name="hello ";
pnode->salary=1000;
第十二章 C与 C++
12.3 C++的核心新特性 —— 类
12.3.1 类
以下是一个有关“人”的类的定义
class CHuman // class ——类定义关键字
{char name[ 20]; //
int age;
void GetInfo() //
{……
}
void OutInfo()
{……
}
};
第十二章 C与 C++
12.3.2 类实例
类的定义格式与结构体类型定义格式类似, 其含义也类
似, 均是定义了一种新的数据类型, 要作为程序处理的对象 。
对于结构体类型, 接着要定义结构体型变量以便在程序中引
用 (如第九章中的 struct staff worker1,worker2; ); 对于类,
则要生成类实例, 又称为类对象 。 其地位如同变量 。 如在上
述的 CHuman类定义之后, 语句,
CHuman human; (类名前不需加关键字 class)
就生成了类 CHuman的实例 human,即为类对象 human分配了
一块可以存放数据和对数据进行处理的程序代码的内存块,
又称为类的实例化 。
第十二章 C与 C++
和内部变量一样, 类对象在定义范围内有效 (如在函数
内定义的类对象, 在函数返回时销毁 )。 一个类可以生成
多个实例 。 也可以用 C++的 new操作符生成类的实例如下,
CHuman *PHuman=new CHuman;
这个语句分配足以放置类对象的内存块并返回其首地
址给这个对象的指针 。 对象所占内存保持到用 delete操作符
释放,
delete PHuman;
C++中多用这种分配,销毁模式。
第十二章 C与 C++
12.3.3 类成员的访问
例 12.1 使用C语言全局变量实现有关一个人的信息的输
出操作 。
# include <string.h>
# include <stdio.h>
char name[ 20] ; /* 两个全局变量 */
int age;
void GetInfo()
{strcpy(name, " Li -Li" );
age=22;
}
第十二章 C与 C++
void OutInfo()
{count<<" name," <<name<<end; /* << 为输出显示符 */
count<<" age," <<age<<end;
}
/* 下面是一些其它的函数 */
function1()
{…… // 此函数内可调用 GetInfo()和 OutInfo()及全局变量 name[]和 age
}
Function2()
{…… // 此函数内可调用 GetInfo()和 OutInfo()及全局变量 name[]和 age
}
main()
{ char ch;
GetInfo();
OutInfo();
……
}
第十二章 C与 C++
图 12.1 C程序中全局变量不安全性
函数
G e t I n f o ( )
O u t I n f o ( )
n a m e [ 2 0 ]
a g e
f u n c t i o n 1 (
)
f u n c t i o n 2 (
)
函数
第十二章 C与 C++
例 12.2 用 C++语言定义一个有关人的“类”
class CHuman // class ——类的定义符
{ private,// 以下为私有变量,可以也只能由该类的成员函数调用
char name[ 20];
int age;
public,//
int GetInfo()
{ ……
}
int OutInfo()
{……
}
}; // 类定义结束
第十二章 C与 C++
外部函数
n a m e [ 2 0 ]
a g e
外部函数
G e t I n f o ( )
O u t I n f o ( )
图 12.2 类对私有数据成员的封装
第十二章 C与 C++
怎样正确地调用类成员,
main()
{ CHuman human; // 定义了一个 CHuman类的对象
strcpy( human.name," Li -Li") ; // 错误, 不能访问私有数据成员
human.age=22; // 错误, 同上
human.GetInfo(); // 正确,
human.OutInfo(); // 正确,
}
第十二章 C与 C++
12.3.4 构造函数
在定义一个类时, 直接初始化数据成员是不允许的 。 下
列类的定义的初始化会产生错误,
class C
{private,
int n=0; //
int *pi=&n; //
……
};
第十二章 C与 C++
其实, 在类的定义中初始化是没有意义的, 它只是创建
了一个模板, 类似于 C语言中的结构体类型的定义, 而程序
是不可以直接对类型操作的, 只能对定义在其上的变量操
作 。 所以想要初始化成员, 就必须生成一个类的实例 。
例如,
…… //
void CHuman:,initial(char name[ 20],int age) // 定义一初始化函数
{strcpy(name," " );
age=0; }
…… //
CHuman human; // 生成了一个 CHuman类的实例 human
human.initial(name,age); // 初始化类实例 hu
man
第十二章 C与 C++
初始化成员变量的更好办法是定义一个特殊的成员函数,
“构造函数”。
class CHuman
{private,
char name[ 20];
int age
public,
CHuman() // 定义构造函数,它的名称与类的名称一样
第十二章 C与 C++
{strcpy(name," " );
age=0;
}
void GetInfo()
{……
}
void OutInfo()
{……
};
}
第十二章 C与 C++
12.3.5 析构函数
析构函数也是自动执行的, 但它与构造函数相反, 是
在程序结束时执行, 它负责在程序撤消类的对象时, 释放
所占资源 。 例如,
~CHuman() //
{
delete name; // 释放 name所占内存
}
析构函数的名称为构造函数名称前加,~,
第十二章 C与 C++
例 12.3 CHuman类的完整定义
class CHuman
{ private,
char name[ 20] ;
int age;
public,
CHuman() //
{strcpy(name," " );
age=0;
}
第十二章 C与 C++
void GetInfo()
{……}
void OutInfo()
{……}
~CHuman() //
{ delete name; }
};
第十二章 C与 C++
12.3.6 类的继承
类的最重要的特性是继承性, 它很贴近现实世界, 如,
儿子继承父亲的一些特征, 并且拥有自己的特征 。 孙子又
继承了儿子的一些特征, 并且拥有自己的特征 ……。 类也
一样, 它的一些特性是可以继承的 。 下面我们将前面的有
关人的类增加一些数据成员, 并派生出一个, 学生, 的类,
class CHuman // 重新定义一表示人的类 CHuman
{ private,
char *m -name;
int m -age;
char *m -sex;
float m -height;
第十二章 C与 C++
public,
CHuman() //
{m -name= " ";
m -age=0;
m -sex= " ";
m -height=0.0;
}
void GetInfo(char *name,int age,char *sex,float height)
{m -name=new char[ strlen(name)+1] ;
m -name=name;
m -age=age;
m -sex=sex;
m -height=height;
}
第十二章 C与 C++
void print()
{cout<< "Name,"<<m -name;
cout<< "Age,"<<m -age;
cout<< "Sex,"<<m -sex;
cout<< "High,"<<m -height;
}
~CHuman() //
{delete m -name;
delete m -sex;
}
};
第十二章 C与 C++
以上是一个, 人, 的类, 现在, 我们需要描述一个学生
的一些特征 。 当然, 学生是属于, 人, 的, 所以, 有关人的
特性我们不应该重复, 可以从, 人, 的类中, 派生, 出我们
所要定义的, 学生类,, 继承, 人, 类中所有的属性, 再
增加些学生特有的属性, 定义, 学生类, 如下,
class CStudents,public CHuman // 表示类 CStudents是从类 Chuman
{private,//
char *m -schoolname; // 校名
int m -grade; // 年级
第十二章 C与 C++
public,
void printstu()
{cout<< "Schoolname,"<<m -schoolname;
cout<< "Grade,"<<m -grade;
}
void GetStuInfo(char *schoolname,int grade )
{m -schoolname=new char[ strlen(schoolname)+1] ;
m -schoolname=schoolname;
m -grade=grade;
}
第十二章 C与 C++
CStudents() //
{m -schoolname= " ";
m -grade=0;
}
~CStudents() //
{ delete m -schoolname;
}
};
第十二章 C与 C++


G e t I n f o ( )
P r i n t ( )
G e t S t u I n f o (
)
P r i n t s t u ( )
m _ n a m e
m _ a g e
m _ h e i g h t
m _ s e x
m _ s c h o o l n a m
e
m _ g r a d e
C H u m a n 类
C S t u d e n t 类新增部分
公有 私有
图 12.3 基类及其派生类的成员可访问图
第十二章 C与 C++
12.4 面向对象程序设计
12.4.1 从面向过程到面向对象
12.4.2 什么是面向对象
面向对象程序设计是面向对象理论在程序设计中的应
用, 面向对象理论的应用范围则更广 。 面向对象系统有三
大特性,封装性, 继承性和多态性 。 面向对象的概念可以
由如下公式表示,
面向对象 =对象 +类 +继承 +
第十二章 C与 C++
1,
在面向对象的系统中, 对象是基本的, 运行时的实体,
它既包括数据 (属性 ),也包括作用于数据的操作 (行为 )。 所
以一个对象把属性和行为密封成一个整体 。 从程序设计者
来看, 对象是一个程序模块;从用户来看, 对象为他们提
供了所希望的行为 。
第十二章 C与 C++
2,类
一个类定义了一组大体上相似的对象 。 一个类所包含
的方法和数据描述了一组对象的共同行为和属性 。 把一组
对象的共同特性加以抽象并存贮在一个类中的能力, 是面
向对象技术最重要的一点 。
类是在对象之上的抽象 。 有了类以后, 对象则是类的
具体化, 是类的实例 。 类可以有子类, 同样也可以有父类,
形成层次结构 。
第十二章 C与 C++
3,
继承性是父类和子类之间共享数据和操作的机制 。 这是类
之间的一种关系, 在定义和实现一个类的时候, 可以在一个已
经存在的类的基础上进行, 把这个已经存在的类所定义的内容
做为自己的内容, 并加入若干新的内容 。
继承性是面向对象程序设计语言的标志 。 它使程序的可重
用性大大提高 。 因为程序员只要对已有的类加以整理和分类就
有可能重用这些代码, 并且某些软件开发平台如 VC++ 还提供了
大量的微软基础类 (MFC),使程序员可以根据需要进行派生, 剪
裁和修改, 在此基础上集中精力编写子类新增加部分, 大大简
化了大型应用系统的开发复杂性和难度, 提高了软件的开发效
率 。
第十二章 C与 C++
4,通信
各个类的对象间通过消息进行通信 。 所谓消息, 实际
上是一个类的对象要求另一个类的对象执行某个服务的指
令, 指明要求哪一个对象执行这个服务, 必要时还要传递
调用参数 。 系统功能的实现, 就是通过一系列对象消息的
传递, 执行一系列服务达到的, 即系统是用消息将对象动
态链接在一起的 。
面向过程的程序是通过函数调用来运行的, 而面向对
象程序的运行则是通过, 消息, 来驱动的 。 消息中只包含
发送者的要求, 但并不指定接收者具体的处理方法 。 实现
方法由接收消息者来确定 。
第十二章 C与 C++
消息有很多种, 常见的为 · 单击鼠标左键 /右键 。
· 双击鼠标左键 /右键 。
·
例如,单击鼠标左键显示某人信息 。
首先, 创建鼠标左键单击的消息响应函数 LButtonDown(),
在鼠标左键按下后, 系统会自动调用此函数 。
其次, 加入处理消息的代码, 即:显示信息 。
LButtonDown()
{CHuman man; // 生成的 "人类 "的对象
man.GetInfo("王军 ",23,"男 ",1.75);
man.print();
}
第十二章 C与 C++
12.4.3
图 12.4 面向过程的软件开发过程
分析
设计
编码
测试
维护
第十二章 C与 C++
具体各步解释如下,
(1) 分析阶段。
(2) 设计阶段。
(3) 编码阶段。
(4) 测试阶段。
(5) 维护阶段。
第十二章 C与 C++
分析
设计
( b )( a )
分析
设计
实现
图 12.5 面向对象的软件开发过程
第十二章 C与 C++
12.4.4 Windows应用程序开发
Windows的运行机制有两个主要特点,
(1) 消息驱动。
① 做一些初始化工作,登录, 窗口类,, 建立窗口等。
② 执行消息循环。
③ 等待 WM -QUIT消息,结束应用程序
(2) 多任务。