




已阅读5页,还剩177页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C+程序设计,C+语言简介,C+: C+之父- 贝尔实验室 Bjarne Stroustrup,C+是更好的C,C+语言简介,一、C+与C的关系 1、C+与C保持兼容 C+文件的后缀为.CPP 2、C+对C语言作了一些扩充和改进 3、C+增加了面向对象的机制,怎样学好程序设计语言,程序=数据结构+算法 掌握语法:基本概念要清晰,基本语法要熟练 掌握数据结构:把握如何将现实生活中的事物抽象为程序中数据结构的方法 掌握算法:学会如何规划计算机的工作方式与顺序的方法 掌握编程思想:用计算机的思维方式去思维,学习C+,C+是语法最复杂,功能最灵活的程序设计语言 学习C+,一方面要注意C+与C在语法上的不同点,更重要的是能从面向过程式的思维方式转向面向对象的思维方式。 学C+,可以对计算机基础知识有更深的理解,可以增强软件开发基本训练。重在实践,对很多现象要知其所以然。从这个意义上说,C+是软件开发人员的“思维体操”。,参考书籍,C+编程环境的建立,Windows平台下C+的集成开发环境: Microsoft Visual C+ Borland C+ Builder Linux下可以采用命令行开发C+程序 vi 编辑源文件 gcc 编译源文件 kdevelop 等IDE,C+语言简介,二、C+程序的构成 /* C+程序示例 */ #include /系统头文件 using namespace std; int main() int a,b,result; coutab; result=a+b; cout“n The sum of“a“+“b“=“ resultendl; ,C+语法,字符集,英文字母: az,AZ,数字: 09,特殊字符:,C+语法,词法记号,关键字: class, new, virtual, inline,bool,,标识符: hello, _t, v1,m_result,操作符: +,-,*,/,文字: 数据,字符串,字符,布尔文字,分隔符: “()“, “, “,“, “:“, “;“,数据类型,布尔型 (bool),字符型 (char),整型 (int),基本数据类型,实数型(float),自定义类型,true or false,short, long/signed, unsigned,float, double, long double,signed/unsigned,typedef,常量,声明:,由用户自定义,用法: - 必须初始化; -在定义后不能再改变其值,常量类型: 整形常量,实型常量,字符常量, 字符串常量,布尔常量,const T = ;,声明:数据类型 变量名1,变量名2,变量名n,变量,变量在使用之前需要首先声明其类型和名称,在声明一个变量时可以给它赋初值,变量的存储类型: Auto:采用堆栈方式分配内存空间,属于暂时性存储,其存储空间可被若干变量多次覆盖使用。 Register:存放在通用寄存器中。 Extern:在所有程序和程序段中都可以引用。 Static:在内存中是以固定地址存放的,在整个程序运行期间都有效。,枚举类型,将变量列举出来就构成了枚举类型,定义: enum ; e.g.- enum keyword ASM, AUTO, BREAK ;,枚举类型有默认值,它们依次为: 0,1,2,; - ASM=0, AUTO=1, BREAK=2;,也可以在申明时另行制定枚举元素的值,如. - ASM=1, AUTO=5;,BREAK=6,数组,数组是具有一定顺序关系的若干对象的集合体,组成数组的对象称为该数组的元素,声明:数据类型 标识符常量表达式1常量表达式2,常量表达式中数据类型必须是unsigned int,初始化: - int v14 = 1, 2, 3, 4 ; - char v2 = a, b, c, 0 ; - char v32 = a, b, 0 ; /error - char v43 = a, b, 0 ; /ok - int v52 3 = 1, 2, 3,4,5,6 ;,数组名是一个常量,代表着数组在内存中的起始地址,数组元素的调用 数组名下标1下标2,数组,e.g. #ingculde Void main() int a10,b10; int i; for (i=0;i10;i+) ai=i*2-1; b10-i-1=ai; for (i=1;i10;i+) cout“a“i“”ai; cout“b“i“”biendl; ,结构体,结构体是由不同的数据类型组成的整体. 是类的简单形式。,结构体声明,Struct student /学生信息结构体 int num; /学号 char name20; /姓名,字符型数组 char sex; /性别 int age; /年龄 char score; /成绩 char addr30 /住址 ,指针,指针是用于存放内存单元地址的数据类型,声明:数据类型 *标识符,char c1 = a; char* p = ,在上例中: P为指针变量,指向内存地址 *p为指针所指向的内容,该内存单元中的数据 &c1为取出为变量c1分配的地址,指针数组,如果数组的每一个元素都是指针变量,这个数组就是指针数组,其元素为同一类型的指针,声明: 类型名T *数组名下表表达式,int arr1=1,0,0,arr2=0,1,0,arr3=0,0,1; int *p3; p0=arr1; p1=arr2;p2=arr3;,指针,指向数组的指针,数组名就是一个指向它第一个元素地址的指针 - int v = 1, 2, 3, 4 ; - int* p1 = v; - int* p2 = ,其他应用: 指针作为函数的参数 指针型函数 (返回值为指针类型) 指向函数的指针 数据类型 (*函数指针)(形参表) 对象指针,操作符,释放存储空间,- new/new: 创建动态对象. - delete/delete: 释放动态对象.,new () /individual objects new ; /arrays,- new/new 返回指向新分配内存首地址的指针.,delete ; /individual objects delete ; /arrays,用delete销毁用new创建的动态存储,函数,1 函数的声明 2 返回值 3 参数传递 4 作用域 5 函数重载 6 带默认形参值的函数 7 内联函数,函数的声明,函数必须先定义后调用. 声明中给出函数的名称,返回值类型,以及行参的类型和数量 调用其他函数的函数称为主调函数,被其他函数调用的函数称为被调函数,int number(); char* strcpy(char* to, const char* from); void exit(int);, ();,在函数声明过程中可以不给出形参名称,函数的声明,在函数声明中可能包含参数名,但编译器会忽略这些名字。参数传递在初始化进行。 参数类型将被检查,并在必要时进行强制类型转化.,double sqrt(double); /call sqrt() with the argument double(2) double sr2=sqrt(2); /error: sqrt() requires an argument of type double double sq3=sqrt(“three“);,函数的定义,程序中调用的每一个函数都必须在某处定义. 函数定义相当于带函数体的函数声明,extern void swap(int*, int*); /a declaration void swap(int* p, int* q) /a definition int t=*p; *p=*q; *q=t; ,声明和定义的返回值类型必须相同. 行参的标识符可以不同,但类型必须相同.,the body of the function,举例说明,#include void fun1(),fun2(),fun3(); /函数声明 void main() cout“It is in main. “endl; fun2(); cout“It is back in main. “endl; void fun1() cout“It is in fun1. “endl; fun3(); cout“It is back in fun1. “endl; ,举例说明,/example41 void fun2() cout“It is in fun2. “endl; fun1(); cout“It is back in fun2. “endl; void fun3() cout“It is in fun3. “endl; ,It is in main. It is back in fun1. It is in fun2. It is back in fun2. It is in fun1. It is back in main. It is in fun3.,返回值,形参表(type1,type2,typen) 作用是实现主调函数和被调函数的联系,函数的返回值由return语句给出 无返回值的函数不必写return,其类型表示符为void 一个函数可以有多个返回值.,return ; or return;,返回值,/1 is implicitly converted to double(1) double f() return 1; ,对本地变量的指针和应用不应该作为返回值.,int* fp() int local=1; return /bad,-函数每调用一次,它的参数和本地变量都要被重新创建.,返回值的类型将被检查,所有标准的和自定义的类型将被转化.,参数传递,语法,当函数被调用时,存储器准备接受行参(Formal arguments). 行参将被相应的实参初始化. 实参的类型将按行参类型检查.,();,参数传递的方式,形参类型为C的各种数据类型,值调用,/ #include void swap1(int x,int y) int temp; temp=x; x=y; y=temp; cout“x=“x“, “y=“yendl; void main() int a(5),b(9); swap1(a,b); cout“a=“a“, “b=“bendl; ,Output: x=9,y=5 a=5,b=9,地址调用,#include void swap2(int *x,int *y) int temp; temp=*x; *x=*y; *y=temp; cout“x=“*x“, “y=“*yendl; void main() int a(5),b(9); swap2( ,Output: x=9,y=5 a=9,b=5,引用调用,#include void swap3(int ,Output: x=9,y=5 a=9,b=5,引用调用,#include int ,Output: 1 3 11 7 ,11,r,参数调用,参数传递,常量参数,目的:提高效率 特点: - 被调函数不能改变常量参数的值.,void f(const Large& arg) /the value of “arg“ cannot be changed without /explicit use of type conversion ,/assume that g() modifies arg void g(Large,参数传递,int strlen(const char*); char* strcpy(char* to, const char* from); int strcmp(const char*, const char*);,- 文字,常量,需强制转化的参数可以通过 const& argument来传递.,参数传递,float fsqrt(const float /pass ref to temp holding float(d) ,float update(float /error:type conversion required ,作用域,作用域是指声明的有效区域. 文件作用域 函数作用域 块作用域,作用域,int a; /文件作用域 void main() int b; /函数作用域 If(b=0;b=10;b+) int c; /块作用域 c+=b; ,函数重载,两个以上的函数,取相同的函数名,但是形参的个数或者类型不同,这就是函数的重载。 函数重载让功能相近的函数在相同的作用域内以相同的函数名定义,便于使用和记忆,void print(double); void print(long); void f() print(1L); /print(long) print(1.0); /print(double) print(1); /error:ambiguous ,函数重载,注意的问题,编译器必须能够找到要调用的函数. 调用函数必须和形参最佳匹配: - 形参数量; - 形参类型; 编译器不能通过形参名来区分函数 编译器不能通过返回值来区分函数 如果没有最近匹配的函数,将会出错. 函数重载与函数的声明顺序无关.,函数重载,void print(int); void print(const char*); void print(double); void print(long); void print(char); void h(char c, int i, short s, float f) print(c); /精确匹配: print(char) print(i); /精确匹配: print(int) print(s); /integral promotion: print(int) print(f); /float to double: print(double) print(c); /精确匹配: print(char) print(49); /精确匹配: print(int) print(0); /精确匹配: print(int) print(“a“); /精确匹配: print(const char*) ,函数重载,返回值不能用于区分函数,int add(int ,int); void add(int,int); /error:重新定义,形参名不能用于区分函数,int add(int x,int y); void add(int a,int b); /error: 重新定义,函数体的功能应该类似.,int add(int x,int y) return x+y; double add(double x,double y) return x-y; ,举例说明,#include int add(int,int); /形参类型不同 double add(double,double); / void main() coutadd(5,10)endl; coutadd(5.0,10.5)endl; int add(int x,int y) cout“int“endl; return x+y; ,举例说明,double add(double x,double y) cout“double“endl; return x+y; ,Output: int 15 double 15.5,举例说明,/#include int min(int a,int b); /形参数量不同 int min(int a,int b,int c); / int min(int a,int b,int c,int d); / void main() coutmin(13,5,4,9)endl; coutmin(-2,8,0)endl; int min(int a,int b) return ab?a:b; ,举例说明,int min(int a,int b,int c) int t=min(a,b); return min(t,c); int min(int a,int b,int c,int d) int t1=min(a,b); int t2=min(c,d); return min(t1,t2); ,Output: 4 -2,带默认形参值的函数,函数在定义时可以给出默认的形参值,调用时如果给出实参,则用实参初始化形参,如果没有给出实参,则采用预先定义的默认值;,int add(int x,int y=0); or int add(int x,int y=0) return x+y; ,带默认形参值的函数,默认形参值必须按从右向左的顺序定义.,int add(int x,int y=5,int z=6); /ok int add(int x=1,int y=5,int z); /error int add(int x=1,int y,int z=6); /error,默认形参值应该在函数原型中给出,/默认形参值在函数原型 中给出 int add(int x=5,int y=6); void main(void) add(); int daa(int x,int y) return x+y;,带默认形参值的函数,在相同的作用域内,默认形参的说明应保持唯一,但如果在不同的作用域内,允许说明不同的默认形参.,带默认形参值的函数重载时应注意.,void fun(int x, int y=0); void fun(int x); void g() fun(3); /error,匹配不明确: fun(3) or fun(3,0)? ,带默认形参值的函数,void fun(int x=7); /error:保持唯一 void fun(int x=8); void g() /ok:作用域不同 void fun(int x=9); / ,举例说明,/ #include void fun(int a=1,int b=3,int c=5) cout“a=“a“, “b=“b“, “ “c=“cendl; void main() fun(); fun(7); fun(7,9); fun(7,9,11); cout“OK! “endl; ,Output: a=1,b=3,c=5 a=7,b=3,c=5 a=7,b=9,c=5 a=7,b=9,c=11 OK!,内联函数,函数的调用会降低程序的执行效率,因为调用函数时需要保存现场和地址,然后转到子程序代码起始地址执行,完毕后转回主调程序,为了提高效率,可以把一些功能简单,规模效,使用率高的函数设计为内联函数. 内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每个调用语句处,内联函数,定义和应注意的问题,inline () / ,inline int add(int x,int y,int z) return x+y+z; void main() int a(1),b(2),c(3),sum(0); sum=add(a,b,c); /replaced by sum=a+b+c; ,内联函数,注意问题: - 内联函数的定义必须出现在第一次被调用之前. - 内联函数体内一般不能有循环和switch语句. - 内联函数不能进行异常接口声明. - 内联函数不能递归使用,内联函数和 #define之间的区别,#include #define f(x) x*x void main() int x(2); coutf(x)endl; coutf(x+1)endl; ,Output: 4 5,#include inline int f(int x) return x*x; void main() int x(2); coutf(x)endl; coutf(x+1)endl; ,Output: 4 9,f(x) is replaced 2*2 f(x+1) is repalced 2+1*2+1,f(x) is replaced 2*2 f(x+1) is repalced 3*3,函数模板,对于参数类型不同,但功能完全相同的函数,用函数模板可以把它们编如一个函数体内。 函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,简化重载函数的函数体设计,定义:template 函数定义,举例说明,/求绝对值函数的模板 #include Template T abs (T x) return x0? x : x; void main() int n=-5; double d=-5.5; Coutabs(n)endl; 输出: Coutabs(d)endl; 5 5.5,类与对象,面向对象的思想 OOP的基本特点 类概念和声明 对象 构造函数 析构函数 内联成员函数 拷贝构造函数,面向对象的程序设计特点,面向对象的程序设计方法就是运用面向对象的观点来描述现实问题,然后用计算机语言来描述并处理该问题。这种描述和处理是通过类和对象实现的,是对现实问题的高度概括,分类和抽象. 抽象:是指对具体问题(对象)进行概括,抽出一类对象的公共性质并加以描述的过程。 封装:将抽象得到数据成员和代码相结合,形成一个有机的整体,也就是将数据与操作数据的行为进行有机的结合。 继承:在保持原有类特性的基础上,进行更具体更详细的说明 多态:类中具有相似功能的不同函数使用一个名称来实现,回顾:面向过程的设计方法,重点: 如何实现细节过程,将数据与函数分开。 形式: 主模块+若干个子模块(main()+子函数)。 特点: 自顶向下,逐步求精功能分解。 缺点: 效率低,程序的可重用性差。,面向对象的方法,目的: 实现软件设计的产业化。 观点: 自然界是由实体(对象)所组成。 程序设计方法: 使用面向对象的观点来描述模仿并处理现实问题。 要求: 高度概括、分类、和抽象。,OOP的基本特点-抽象,抽象是对具体对象(问题)进行概括,抽出这一类对象的公共性质并加以描述的过程。 先注意问题的本质及描述,其次是实现过程或细节。 数据抽象:描述某类对象的属性或状态(对象相互区别的物理量)。 代码抽象:描述某类对象的共有的行为特征或具有的功能。 抽象的实现:通过类的声明,抽象实例钟表,数据抽象: int Hour, int Minute, int Second 代码抽象: SetTime(), ShowTime(),抽象实例钟表类,class Clock public: void SetTime(int NewH, int NewM, int NewS); void ShowTime(); private: int Hour,Minute,Second; ;,OOP的基本特点-封装,将抽象出的数据成员、代码成员相结合,将它们视为一个整体。 目的是曾强安全性和简化编程,使用者不必了解具体的实现细节,而只需要通过外部接口,以特定的访问权限,来使用类的成员。 实现封装:类声明中的,封装,实例: class Clock public: void SetTime(int NewH,int NewM, int NewS); void ShowTime(); private: int Hour,Minute,Second; ;,特定的访问权限,OOP的基本特点-继承与派生,是C+中支持层次分类的一种机制,允许程序员在保持原有类特性的基础上,进行更具体的说明。,OOP的基本特点-多态性,多态:同一名称,不同的功能实现方式。 目的:达到行为标识统一,减少程序中标识符的个数。 实现:重载函数和虚函数,c+中的类,类是具有相同属性和行为的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包括属性和行为两个主要部分。 利用类可以实现数据的封装、隐藏、继承与派生。 利用类易于编写大型复杂程序,其模块化程度比C中采用函数更高。,类,类的定义 数据成员 公有 访问权限 私有 类成员函数 保护 class 类名 public: 成员函数、数据成员 private: 数据成员、成员函数 ;,类,举例说明,class Date public: void SetDate(int y,int m,int d); int IsLeapYear(); void Print(); private: int year,month,day; ; / 成员函数定义 /,关键字,类名,成员类型,分号,成员函数,数据成员,类,访问控制属性: public, private, protected “public” 声明了类的外部接口 “private” 只允许本类的成员函数访问,而类外部任何访问都是非法的 “proctected”性质与 “private”性质相似,差别在于继承过程中对产生新类影响不同,inline void Date:Print() coutyear.month.dayendl; void DataPrint(Date/error:外部访问非法 ,类,类的成员函数,函数的原型声明要写在类的主题中. 定义: - 在类的主题内定义; - 在类的外部定义. 在类为定义时,与一般函数稍有不同. 操作符 “:”,函数: 类的成员;,返回值类型 :(),举例说明,class Date public: void SetDate(int y,int m,int d); int IsLeapYear(); void Print() /类内定义 coutyear“.“month“.“dayendl; ; private: int year,month,day; ; void Date:SetDate(int y,int m,int n) /定义 year=y; month=m; day=d; ,类,内联函数: - 在类主体内定义; - 在类的主体内声明,用 inline 在类体外定义. 带默认值的成员函数 重载,举例说明,/class Point public: void Init(int initX,int initY); int GetX(); int GetY(); Private: int X,Y; ;,举例说明,/inline void Point:Init(int initX,int initY) X=initX; Y=initY; inline int Point:GetX() return X; inline int Point:GetY() return Y; ,举例说明,/类定义的完整实现 #include class Date public: void SetDate(int y=2002,int m=10,int n=1); int IsLeapYear(); void Print() coutyear“.“month“.“dayendl; private: int year,month,day; ; void Date:SetDate(int y,int m,int n),举例说明,/类定义的完整实现 year=y; month=m; day=d; int Date:IsLeapYear() return (year%4=0 ,举例说明,/类定义的完整实现 date1.SetDate(); /默认参数 date2.SetDate(2000,10,1); coutdate2.IsLeapYear()endl; date1.Print(); date2.Print(); ,Output: 1 2002.10.1 2000.10.1,对象,类的对象是该类的某一特定实体,即类类型的变量。 声明形式: 类名 对象名; 例: Clock myClock;,对象,类中成员互访 直接使用成员名 类外访问 使用“对象名.成员名”方式访问 public 属性的成员,对象的初始化,5.3.1 构造函数和析构函数,class Date /date.h public: Date(int yy,int mm,int dd) /构造 y=yy; m=mm; d=dd; cout“Constructor called. “endl; Date() /析构 cout“Destructor called. “endl; void Print() couty.m.d.endl; private: int y,m,d; ;,构造函数和析构函数,在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态. 构造函数与类同名. 构造函数能够重载. 构造函数不能有返回值. 在对象被创建时自动调用.,用来完成对象将删除前的一切清理工作. 析构函数名由类名前加()组成 . 不接受任何参数,不能被重载. 析构函数没有返回值. 析构函数在对象生存期即将结束时由系统自动调用.,构造函数和析构函数,Date today=Date(23,6,1983); Date xmas(25,12,1990); Date my_birthday; /error:没有初始化 Date release1_0(10,12);/error:缺少形参,class Date / Date(int y=2002,int m=10,int=1);/缺省参数 Date(int); /重载构造函数 Date(const char*); ; Date today; /Date today(2002,10,1); Date tomorrow(2); Date(“July 4, 1998“);,构造函数和析构函数,拷贝初始化构造函数,int i(5); int j=i; / 拷贝构造 today(2002,10,10); Date tomorrow=today; /拷贝构造,其功能是:使用一个类的对象来初始化该类的另一个新建对象。 .,Format:类名:拷贝构造函数名(const 类名&对象名),在类定义时没有定义任何构造函数时,则编译器自动生成一个不带参数的缺省空构造函数。 .,举例说明,/构造和析构 /tpoint.h class TPoint public: TPoint(int x,int y) X=x;Y=y; TPoint(TPoint ,举例说明,/构造和析构 TPoint:TPoint(TPoint ,#include #include “tpoint.h“ TPoint f(TPoint Q); void main() TPoint M(20,35),P(0,0); TPoint N(M);,M is a created object,N is a creating object,举例说明,/ P=f(N); cout“P=“P.Xcoord()“, “ P.Ycoord()endl; TPoint f(TPoint Q) cout“OK! “endl; int x,y; x=Q.Xcoord()+10; y=Q.Ycoord()+20; TPoint R(x,y); return R; ,Pass by data value,Return Rs data value,举例说明,Output: Copy_initialization Constructor called. Copy_initialization Constructor called. OK! Copy_initialization Constructor called. Destructor called. Destructor called. Destructor called. P=30,55 Destructor called. Destructor called. Destructor called.,Temporary object,类的应用举例,一圆型游泳池如图所示,现在需在其周围建一圆型过道,并在其四周围上栅栏。栅栏价格为35元/米,过道造价为20元/平方米。过道宽度为3米,游泳池半径由键盘输入。要求编程计算并输出过道和栅栏的造价。,#include const float PI = 3.14159; const float FencePrice = 35; const float ConcretePrice = 20; /声明类Circle 及其数据和方法 class Circle private: float radius; public: Circle(float r); /构造函数 float Circumference() const; /圆周长 float Area() const; /圆面积 ;,/ 类的实现 / 构造函数初始化数据成员radius Circle:Circle(float r) radius=r / 计算圆的周长 float Circle:Circumference() const return 2 * PI * radius; / 计算圆的面积 float Circle:Area() const return PI * radius * radius; ,void main () float radius; float FenceCost, ConcreteCost; / 提示用户输入半径 coutradius; / 声明 Circle 对象 Circle Pool(radius); Circle PoolRim(radius + 3);,/ 计算栅栏造价并输出 FenceCost = PoolRim.Circumference() * FencePrice; cout “Fencing Cost is ¥“ FenceCost endl; / 计算过道造价并输出 ConcreteCost = (PoolRim.Area() - Pool.Area()*ConcretePrice; cout “Concrete Cost is ¥“ ConcreteCost endl; 运行结果 Enter the radius of the pool: 10 Fencing Cost is ¥2858.85 Concrete Cost is ¥4335.39,内容,类的继承与派生 类成员的访问控制 派生类的构造、析构函数 类成员的标识与访问 多态性 运算符重载 虚函数 纯虚函数 抽象类,继承性和派生类,概念 - 继承性:就是在一个已存在的类的基础上建立一个新类 - 基类:已存在的类称为“基类”或“父类” - 派生类:新建立的类称为“派生类”或“子类” 基类和派生类的关系 - 基类时派生类的提取,派生类是基类的具体化. - 派生类是基类的合成. - 派生类可以作为基类,继承性和派生类,继承的目的:实现代码重用。 派生的目的:当新的问题出现,原有程序无法解决(或不能完全解决)时,需要对原有程序进行改造。,概念,单继承和多继承,单继承:一个类可以有多个派生类,但每个派生类只有一个基类 多继承: 一个派生类具有多个基类 多层次继承:一个派生类具有基类和间接基类。,继承方式,不同继承方式的影响主要体现在: 1、派生类成员对基类成员的访问控制。 2、派生类对象对基类成员的访问控制。 三种继承方式 公有继承 私有继承 保护继承,公有继承(publlic): 基类的公有成员和保护成员成为派生类中的公有成员和保护成员。而基类的私有成员不能被派生类(新建立的部分)引用,只有基类的成员函数可以引用它 私有继承(private):基类的公有成员和保护成员成为派生类中的私有成员。而基类的私有成员成为派生类不可访问的成员,只有基类的成员函数可以引用它 保护继承(protected):基类的公有成员和保护成员成为派生类中的保护成员。而基类的私有成员成为派生类不可访问的成员,只有基类的成员函数可以引用它,派生类的三种继承方式,派生类中的成员,成员层次,成员包括基类中的成员和派生类自身的成员.,派生类定义格式,class 派生类名:继承方式1 基类名1,继承方式2 基类名2 派生类新定义成员 ; a、缺省继承方式是私有继承方式; b、根据不同的继承方式,基类分别称为公有基类、私有基类和保护基类。,举例说明,class Location public: void InitL(int xx,int yy); void Move(int xOff,int yOff); int GetX() return X; int GetY() return Y; private: int X,Y; ; void Location:InitL(int xx,int yy) X=xx; Y=yy; ,举例说明,void Location:Move(int xOff,int yOff) X+=xOff; Y+=yOff; class Rectangle:public Location/公有继承 public: void InitR(int x,int y,int w,int h); int GetH() return H; int GetW() return W; private: int H,W; ; void Rectangle:InitR(int x,int y,int w,int h) InitL(x,y);,举例说明,W=w; H=h; #include void main() Rectangle rect; rect.InitR(2,3,20,10); /可以访问基类的GetX rect.Move(3,2); coutrect.GetX()“, “rect.GetY()“, “ rect.GetH()“, “rect.GetW()endl; ,Output: 5,5,10,20,通过派生类的对象能访问基类的public成员。,举例说明,class Rectangle:private Location/私有继承 public: void InitR(int x,int y,int w,int h); int GetH() return H; int GetW() return W; private: int W,H; ; void Rectangle:InitR(int x,int y,int w,int h) InitL(x,y); /直接继承 W=w; H=h; ,举例说明,#include void main() Rectangle rect; rect.InitR(2,3,20,10); rect.Move(3,2); coutrect.GetX()“, “rect.GetY()“, “ rect.GetH()“, “rect.GetW()endl; ,通过派生类的对象不能访问基类中的任何成员。,举例说明,class A protected: int x; int main() A a; a.X=5; /错误 ,通过派生类的对象不能访问基类中的任何成员,举例说明,class A protected: int x; class B: public A public: void Function(); ; void B:Function() X=5; /正确 ,派生类的构造和析构函数,构造函数,基类的构造函数不被继承,派生类中需要声明自己的构造函数。 声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化,自动调用基类构造函数完成。,构造函数的语法形式,派生类名:派生类名() :( 参数表-1),( 参数表-n 派生类新增成员的初始化语句 ;,派生类的构造和析构函数,注意 - 在构造函数的参数表中,需要给出初始化基类数据、新增对象数据及一般成员数据所需的全部参数. - 初始化顺序是: & 基类构造函数 & 子对象构造函数 & 派生类构造函数体中的内容 -多基类继承时基类构造函数的执行顺序取决于定义派生类时所指定的各基类顺序,与构造函数列表顺序无关 .,举例说明,/构造函数 #include class B1 public: B1(int i) b1=i; cout“Constructor B1.“endl; void Print() coutb1endl; private: int b1; ; class B2 public: B2(int i) b2=i; cout“Constructor B2.“endl; void Print() coutb2endl;,举例说明,/ private: int b2; ; class B3 public: B3(int i) b3=i; cout“Constructor B3.“endl; int Getb3() return b3; private: int b3; ; class A:public B2,public B1 public: A(int i,int j,int k,int l);,多基类继承,举例说明,/example71 void Print(); private: int a; B3 bb;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 技术创新对车辆残值率影响机制-洞察及研究
- 多语言环境禁止表的自适应构建技术-洞察及研究
- 护理概论考试题及答案
- 高校学生学习习惯培养方案
- 数学思维微课设计与教学策略
- 小学英语词汇基础与教学练习汇编
- 制造企业设备维护标准操作程序
- 初中英语单元教学设计与反思报告
- 银行信贷风险控制操作流程标准
- 房地产企业采购流程与岗位职责详解
- 桩基础平法施工图(平法施工图识读)
- GB/T 9113-2010整体钢制管法兰
- GB/T 23338-2018内燃机增压空气冷却器技术条件
- 癫痫的急救与护理课件
- 海姆立克急救法完整版本课件
- 国家地表水环境质量监测网采测分离实施方案课件
- 控压钻井技术及实践培训讲义工艺课件
- 厚度仪点检表
- 北京市水利工程维修养护定额
- 自然拼读法在小学英语教学中的应用的实践研究
- 无领导小组面试评分表模板
评论
0/150
提交评论