C/C++程序设计
1
一、向对象理论鸟瞰二、面向对象程序设计的概念三、面向过程和面向对象编程四、类的声明五、对象的定义
C/C++程序设计
2
一、向对象理论鸟瞰面向对象理论代表了以往计算机语言的经验总结和发展,而 C++语言因其包容 C语言和面向对象理论的雄浑气度而出类拔萃。
C++是典型的混合编程语言。
学会 C++可以顺利打通面向过程和面向对象之间的人为障碍,从而进入混合程序设计的自由王国。
C/C++程序设计
3
面向对象理论是一种模块化的整体组合技术,是结构化程序设计的自然扩展,面向对象理论站在文本替换的编译角度看是一种封装的封装,这种双层封装带来的好处有,
1,程序容易维护
2,代码容易扩展
3,算法容易重用面向对象理论适宜于开发大型软件。 C语言是一门灵活快捷高效的语言。程序设计最重要的是提供解决问题一个高效快捷灵活的方案。
新的编译环境是一个高度集成的混合调试环境 (单独的 C
编译器逐步退出市场 ),有充分的理由期望混合编程的 C++语言成为开发操作系统的主流语言。
C/C++程序设计
4
二、面向对象程序设计的概念
1,对象 object
2,类 class(类类型简称为类)
3,封装 encapsulation
4,继承 inheritance
5,多态 polymorphism
C/C++程序设计
5
1,对象 object
简单地可以将对象视为结构变量。
变量是对象最基本的单元,对象是不同类型变量的一个有序集合;
结构变量代表内存单元相对静态的数据状态,其变化通过函数来实现,函数表现作用于数据结构的算法,本身也是内存中称之为代码的特殊数据。
C/C++程序设计
6
对象是包含数据状态与作用于这些数据状态的若干成员函数的数据集合。
可以将对象视为一个动态的数据结构,对象对其上的函数调用加上了一个约束机制,函数优先访问与对象有关的数据。
对象是类类型定义的变量,类声明了对象的数据结构和其上算法的一般行为。
可以向对象发送消息而消息本质上就是函数调用。
对象幕后最终还原为结构变量。
C/C++程序设计
7
2,类 class(类类型简称为类)
类是对象的一个描述、是对象的组织形式、是控制对象特性的共同规则。
C++中类是用关键字 class,struct或 union声明的数据结构。但一般指 class引入的集合数据类型。
类包含着对象数据状态的描述和其上算法的定义,类的数据结构规定对象在内存的存储分配,类的算法直接操作存储空间上的数据。
对象通过类类型名来建立,编译器则通过对象名与类名联合管理数据和算法的协调关系。对象是某个类的实例,类则是对象的抽象。
C/C++程序设计
8
3,封装 encapsulation
面向对象理论中三个重要的支柱是封装、继承与多态。
封装在面向对象的编程前是通过文件级别的模块连接实现的,在 C语言中通过关键字 static限制函数和变量在一个模块的可见性,实际上面向对象的封装效果可以由文件模块的形式来等价的模拟。
类是用户引入的类型,对象是根据该类型产生的一个实例即对象名牵头的存储空间的一片数据。
此类的实例和函数非彼类的实例和函数,此类的函数操作此类的实例所拥有的数据,彼类的函数操作彼类的实例所拥有的数据。
C/C++程序设计
9
面向对象理论中,封装是关于类的外部接口与内部实现访问控制的具体组织形式,是数据与算法层次井然的动态包裹。
系统通过类域分辩符与对象名两者来鉴别数据结构、算法之间的差别。
类域分辨符是形如 CType::的修饰符,CType是用户引入的类名。
深层封装是由关键字 protected 或 private引入的对成员变量和成员函数的访问控制,此种形式的封装是一种精细的封装,是纯粹的面向对象的产物;为了解除这种深层封装的约束,C++特地引进 inline和 friend关键字来加快数据的流通。
C/C++程序设计
10
4,继承 inheritance
继承是在一个已经建立的类的基础上再接着声明一个新类的扩展机制,原先已经建立的类称为基类,在基类之下扩展的类称为派生类,派生类又可以向下充当继续扩展的基类,因此构成层层派生的一个动态扩展过程。
派生类享有基类的数据结构和算法,而本身又具有增加的行为和特性,因此继承的机制促进了程序代码的可重用性。
C/C++程序设计
11
一个基类可以有多个派生类,一个派生类反过来可以具有多个基类,形成复杂的继承树层次体系。
但基类与派生类之间有一个本质的关系:
基类是一个简单的类,描述相对简单的事物,派生类是一个复杂些的类处理相对复杂的现象。
这样一种简单到复杂的关系正是人们认识自然过程的线性映射,软件的可扩充性建立在这样一种对自然的正确回归上便拥有了坚实的基础。
C/C++程序设计
12
5,多态 polymorphism
多态是类继承树层次中与虚函数相关的函数调用的约束应变模式。
多态兼顾软件的可扩充性和软件流程的统一性,表现了变动与约束的结合,多态代表了一种既固定又扩充的作业模式。
包含有虚函数的类称为多态类。
多态建立程序构架的前瞻性规划。
C/C++程序设计
13
多态是这样一种概念:
继承树层次上存在不同的虚函数,表面上一致的接口暗地里对应多种虚函数的实现。
接口是预先定好而且是统一的,多个虚函数都有激活的机会,实际激活的虚函数并不简单是基类声明中的虚函数,
而是基对象指针面向的派生类对象所属的虚函数。
别的程序员可在这种一致的既定接口上方便地追加另外的虚函数,插入虚函数的位置是灵活的。
简单地说多态是继承树上基对象的指针调用派生类的虚函数。
C/C++程序设计
14
三、面向过程和面向对象编程纯面向对象的理论强调其数据与算法的结合性,夸大了面向过程中两者的分离程度。
离散和聚合是一个相对的概念,数组加强了同类型数据的联系程度,结构类型将重复的不同类型的数据整合在一起方便了程序的逻辑组织,类类型则进一步把数据结构和相应的函数有机的容纳为一体使得程序更趋整体更有条理。
C/C++程序设计
15
面向过程的编程中程序员需要根据具体问题建立相应的数据结构,然后同步地构筑凌驾其上的动态代码函数,一定的数据结构总是呼应相关的算法,算法总是操作特定的数据结构。
因此算法与数据结构在面向过程的设计里从来是形影不离的。
面向过程编程也称为结构化程序设计或模块化程序设计。
模块化程序设计的思路是将复杂的问题分解为尽量独立的基本模块,这些基本模块逻辑清晰解决问题直接明确,每一模块内部的语句序列可以分解为顺序、选择和循环结构,
高层模块的外部通过全局变量在模块之间进行数据呼应,模块本身在 C语言中命名为函数。
C/C++程序设计
16
模块化程序设计的定律是,
程序模块 a=算法 a+数据结构 a+系统的库函数程序模块 b=算法 b+数据结构 b+系统的模块库
...,..
程序模块 N=算法 N+数据结构 N+系统的库函数当程序越来越大的时候,程序的模块数 N随之变得很大,
每一相对独立的模块本身引领各级子模块,因此容易构成函数和变量命名的混乱。
C/C++程序设计
17
程序员需要记住算法 M操作相应的数据结构 M,算法 N
操作相应的数据结构 N,算法和数据结构的一一匹配需要通过程序员自己建立一套经验进行管理。不同的程序员有不同的管理方法。
模块化程序设计中,函数和相关的数据结构是若即若离的。凝聚表现在函数通过形参操作特定的数据结构,离散则表现在数据结构上作用一序列函数,两者的联系需要程序员苦心运作。
特别对于大型程序,函数和相应的数据结构手工归类的工作相当可观,因此面向对象的理论应运而生。
面向对象理论将程序员行之有效的经验上升为普遍的方法,这样大型软件的开发就形成了一个新的理论体系。
C/C++程序设计
18
模 块 b 数据结构 b
数据结构 a
函 数 1 模 块 a 函 数 2 数据结构 2
全 局 结构变量函 数 3 数据结构 3 函 数 4 数据结构 4
图 程序设计的模块化
C/C++程序设计
19
模块 b 数据结构 b函 数 3 数据结构 3
模 块 a 数据结构 a
全 局 对 象函数 4 数据结构 4
函 数 1 函 数 2 数据结构 2
图 结构化模块的整体组合 (面向对象的封装 )
C/C++程序设计
20
面向对象的理论将模块 N序列中的数据结构和算法打包成一个类 N,将模块 M序列中的数据结构和算法打包成一个类 M,面向对象理论协助程序员管理类的数据和相关的函数之间的联系。
系统的库函数和一些用户自行开发的全局函数是构成类的基本元素。
全局函数本身是由算法和数据构成的模块。
类上的函数优先操作类上的数据,函数和数据结合在一起,在一定程度上方便了程序的逻辑组织。 函数和数据结构作为一个集成度更高的整体加入程序的模块中,这个高度集成的模块通过类中的函数接口与外部交换信息。
C/C++程序设计
21
[例 ] 用结构实现求两个数的和
#include <stdio.h>
struct CA { int m; long n; };
inline void Initial (CA*const p,int x,int y)
{ p->m=x;p->n=y;}
inline int Add(CA*const ths) { return ths->m+ths->n;}
void Show (CA*const pthis)
{ printf ("%d,%d,%d\t",pthis->m,
pthis->n,Add (pthis)); }
void main( )
{ CA b={10,20}; Show (&b);
Initial (&b,1,2);
Show (&b);
} // 输出,10,20,30 1,2,3
C/C++程序设计
22
[例 ] 用类的形式实现求两个数的和
#include <stdio.h>
class CA
{ public:int m; long n;
public,int Add(){ return this->m+ this->n;}
void Initial (int x,int y) { m=x; n=y; }
void CA:,Show() ;
};
void CA:,Show()
{ printf ("%d,%d,%d\t",m,n,Add()) ; }
void main()
{ CA b= {10,20}; b.Show ();
b.Initial (1,2); b.Show ();
}
// 输出,10,20,30 1,2,3
C/C++程序设计
23
上面两段程序实现相同的功能,两种风格的执行文件即,exe是一样长的 (Debug版本 153kb,Release版本 28kb)。
注意:
严格意义上的集合类型的初始化格式如:
[CA b={10,20};]
要求类和结构没有非公共成员、没有虚函 数、没有基类、
没有提交构造函数。
C/C++程序设计
24
四、类的声明类的成员分两部分:一部分对应数据的状态,称为数据成员或成员数据,另一部分为作用于该数据状态的函数,称为函数成员或成员函数。基类的格式如下 (左边是一般的描述,右边是具体的举例 ):
class 类名 class CType
{ public,{ public,
公共数据成员声明语句; CType* p;
公共成员函数声明语句; void SetP (CType* p);
C/C++程序设计
25
protected,protected:
保护数据成员声明语句; short m_t2;
保护函数成员声明语句; double f2 (...);
private,private:
私有成员数据声明语句; int m_t3;
私有成员函数声明语句; float f3(...);
public,type member; public,char m_t1;
公共成员函数声明语句; void f1(...);
公共成员函数声明语句; long f1(int,...);
type f(T1,T2,…,Tn); void SetData (char,
short,int );
}; };
C/C++程序设计
26
形如 [class CType{成员声明语句 ;};]的类型声明语句建立了一个类名为 CType的类,花括号括起来的成员声明语句描述了成员组成情况。
type,T1,T2,…,Tn 是已声明的类型。
私有的、保护的和公共的数据成员都占有对象的内存。
考虑到边界对齐效应右边声明的具体的类在 vc6.0下占有的内存大小为,sizeof(CType)=12。
在 extern,auto,register和 static关键字中,只有
static关键字可以用来修饰成员,static修饰的成员称为静态成员。类包含两大性质的成员,静态成员和非静态成员。静态数据成员为对象所共享。对象占有的内存是非静态数据成员的贡献,不包括静态数据成员。
C/C++程序设计
27
类可以存在重载函数。
例如,f1(...)和 f1(int,...)就是一对重载函数自身类的实例不可以作为成员,但可以包括指向自身对象的指针。
类中的成员声明是关于集合数据的抽象描述,因此数据成员声明时不指定初始值。
对象、非内联的成员函数和静态数据成员的定义唯一地放置在,cpp实现文件中。
类的声明放置在相应的头文件中,通过 #include指令类的声明被插入到多个,cpp文件。
成员函数如不被调用可以不提供实现部分。
C/C++程序设计
28
五、对象的定义类的声明是关于集合数据的描述,本身不导致内存空间的分配,这与 C的结构声明是一样的。
定义对象是为对象分配内存,并对这一片内存进行适当的初始化处理。
对象定义主要有两种方法:
1,是直接定义
2,是 new运算符定义。
C/C++程序设计
29
其语法格式最简单的为:
CType b,d,e;
//直接定义,类名 对象名序列
CType* pb=new CType();
// new运算符定义直接定义形式就是 C结构变量的定义形式。
在对象定义语句中隐含了对于缺省的公共构造函数调用。
new运算符定义对象是在堆空间诞生对象。 new运算符定义的对象通过对象指针 pb操作。在对象定义点要求相应构造函数是可访问的。
C/C++程序设计
30