c++笔记.doc_第1页
c++笔记.doc_第2页
c++笔记.doc_第3页
c++笔记.doc_第4页
c++笔记.doc_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

面向对象的程序设计1、 概述:1. 对象a. 定义:现实世界中客观存在并可相互区别的事物。b. 特点:每个对象必然有属性。c. 属性:附于对象上一个不变的特征。d. 属性值:一个对象在某个属性上具体的值。每个对象在它的属性上都必须有值。e. 属性是一个对象的静态特征。f. 对象的方法:动态行为成为对象的方法。g. 对象的组成:属性(静态特征)+ 方法程序(动态特征)h. 注意:执行方法的主体为对象。2. 类a. 定义:具有相同属性对象的集合。b. 类属性:类中所有对象的共性。c. 注意:类属性无值。d. 类方法:类中所有对象共同的方法。3. 注意:a. 一个对象必然从属于某个类。b. 系统为每个对象分配存储空间,用来存储一个对象的属性值和方法程序。c. 对象称为类的实例。2、 C+的编程风格1. 告别#define 预定义使用consta. #define宏定义#define标识符#definedMAX200说明:在程序中,用宏名MAX替代200,系统不为MAX分配单元。b. C+中使用const来定义一个常量单元常量单元:只可读取不可写的单元。Const 定义:Const数据类型常变量名 = Const int x = 5;说明:系统为x分配单元,并存储值5,将x单元设置为只读单元。对基本数据类型的变量进行const修饰,将该变量转化为常量。该变量单元转化为只读单元。c. 常量指针指向常量的指针定义:constint*p = 初始化值;Const int a = 79;/*定义常量a*/Const int *p = &a; /*常量指针p,指向常量a*/P单元是变量,指向常量单元*p = 58;/*error,不允许向常量单元赋值*/P = &b;/*true,将使常量指针p指向常量b*/常量指针单元是变量单元,可以指常量单元。常量指针的指向是常量/变量单元。不允许修改常量指针的指向(的单元的)值。常量指针是变量单元,常量指针的值可以被修改,即其指向可以被修改。注意:不可以通过常量指针的指向来修改变量单元(但其可以指向变量单元)。因为其将变量单元看成常量单元。常量指针既可指常量又可指变量。但常量单元只可用常量指针来指。d. 指针常量数据类型 * const 指针名 = 指针常量是指 指针是常量,指针单元是只读的,指针的值不可以被修改。即指针的指向不可改变。指针常量在定义时必须初始化。不允许给指针常量再赋值。Char * const ps = abcld;Ps+ ;/*error*/*ps = x;/*true*/*(ps + 2)= y/*true/e. 指向常量的指针常量Const 类型 *const 名 = 地址指针值不可修改 = 指针的指向不可修改指向的单元值是常量 = 不能修改指针指向的单元的值Constint ci = 6;Int ai;Const int *cosnt cpc = &ci;Ci = 28; /*error,因为ci为常量,不可以修改*/Cpc = &ai;/*error,不可以修改cpc的指向*/*cpc = 28 /*error,不可以通过cpc来修改其指向的单元的值*/Ai = 29 ;/*true*/2. 内联函数a. 使用内联函数的原因编译器在编译阶段遇到函数的调用语句时,若该函数为普通函数,则编译器必须将调用语句和被调用函数通过连接管道连接起来,在运行时可迅速找到被调用函数,降低了程序效率。b. 内联函数在函数发生调用时,可以用内联函数的函数体替代函数的调用语句。定义Inline 数据类型 函数名()内联函数不调用使用内联函数的函数体替代调用的表达式内联函数的函数体不可出现复杂的结构不允许出现switch和循环语句类中的函数都内联3. 动态单元的分配a. 动态单元分配new指针变量= new 数据类型例:Int *p;P = new int;说明:分配一个两个字节的整型单元,使指针变量指向该单元。b. 使用new 分配动态数组指针变量 = new 数据类型个数;Int *p;P = new int5;使指针变量指向由new分配的连续的5个整型单元的首单元。Int *const p = new int5;c. 动态单元的释放释放单个动态单元Delete (指针变量)说明:释放指针指向的动态单元d. 释放动态数组Delete 指针变量;释放指针指向的动态数组。Int *p = new5;Delete P;4. 输入输出流输入 cin输出 cout在c+中输入输出被看作一个输入/输出流 可以同时输入/输出多个不同类型的数。注:系统可自动识别数据的类型流运算符输出流cout 例:int a,b;Cin a b;Cout a b;说明:输出流返回值是流本身,即cout a b; 中 cout area r;Area = pa * r *r;Cout area is area endle;Return 0;3、 C+中类和对象1. C+中的类a. 类定义的组成部分:属性 + 类的数据成员b. 类的说明格式Class 类名Private:/私有成员定义类的私有成员Protected:/受保护的成员,定义类的受保护成员Public:/公有成员定义类的公有成员;c. 类的关键词 class 注:类名在命名时,必须符合标识符命名规则。d. 类体类体必须通过,以表示封装e. 访问权限注意:在类中定义的所有成员,类的对象一定拥有,但不一定可以访问。类的成员必须通过类的对象访问。对象在访问自己成员时,是否可以访问必须查看成员的访问权限。访问权限:Public:公有访问权限在程序的任何位置均可访问,但只能通过对象访问。Private:私有访问权限类外不可直接访问,只可被类的公有成员或友元访问。类外对象不可直接访问。Protected:受保护成员类外不可直接访问,可以被类的友元访问。注:缺省访问权限默认private。访问权限关键字顺序任意,习惯上private,protected,public。不允许对类的数据成员在类中初始化。类中的数据成员定义的数据类型任意。例题:cin_and_coutClass myclass Int x,y;Public:Int z;Void inx(int xx,int yy)X = xx, y = yy;Void print()Cout x is x endl;Myclass my1;My1.z = 5;/因为z为public访问权限,所以类外可通过对象直接访问。My1.inx(3,4);/对象my1通过公有成员int间接访问了私有数据。f. 类的成员函数实现注:类的成员函数在定义时必须符合函数的定义规则实现可以在类内直接实现成员函数,也可将类的成员函数在类体之外实现。如果成员函数在类外实现其依然属于类的成员函数,只是在描述时,放在类外。其定义时为了与普通函数进行区别,必须加上类的作用域运算符。类的作用域: 类名:成员函数表示形式: 数据类型 类名 :成员函数(形参表)若将类的成员函数在类内实现,则该成员函数为内联函数。在函数实现时,函数体不允许出现复杂的结构。在类外实现时,属于调用实现。(可以有复杂的结构)类的成员函数在类外实现时,必须在类中声明。例题:class 定义 pount类,输出任意点p的坐标。#includeusing namespace std;class pount int x,y; public: void output( ) cout p: x,y=x,y属性名;指针变量-方法名(实参)注:一个对象是否可以表示它的属性和方法,要看访问权限例题:私有数据成员x,和y,定义数组对象有4个元素。通过键盘给数组s的四个元素成员输入数据,输出数组s的四个元素。X属性之和,y属性之和。#includeusing namespace std;class myclass private: int x,y; public: void input() cin x y; int getx() return x; int gety() return y; ;int main() myclass my14; /int i; for(int i = 0; i 4; i+) my1i.input(); int sumx = 0; int sumy = 0; for(int i = 0; i 4; i+) sumx +=my1i.getx(); sumy +=my1i.gety(); cout the sum of x = sumx endl; cout the sum of y = sumy x = x;This-y = y;程序this_error中描述了这种情况当类的成员函数的形参,和类的数据成员同名时,在成员函数中,为了加以区别,类的数据成员必须显示由this调用。例:this_errorClass myclass Int x,y;Void inthis(int xx,int yy)This-x = xx;This-y = yy;Void copy(myclass &p)P-x = x;/ p-x = x 等效为 p-x = this-y = y;注:Copy()中代码可以用如下的代码替换:*p = *this;两个同类的对象可相互赋值原理:系统将一个对象的值按字节复制到另一个对象中。4、 C+的函数缺省调用在c+中的所用函数必须先定义后使用(内联函数特殊),若函数出现使用后定义,则必须在使用定义,则必须在使用点之前对函数进行声明。a. 缺省参数在函数调用时,每个形参都必须有对应的实参。由实参向形参传递值。缺省参数时,缺省的是实参。在函数调用时,每个实参按顺序将值传递给对应的形参,没有获取实参值的形参使用默认值。b. 函数默认值设置格式:数据类型函数名(可获得实参的形参,设置默认值的形参)例:Intfun(int x ,int y = 4, int z =5);调用fun(10,11,12);/x=10,y=11,z=12Fun(10,11,);/x=10,y=11,z=5Fun();/x没有设置默认值,所以必须有相应的实参传递值fun(int x=3,int y, int z=4);/error必须自右往左逐个设置分析:三个形参均不设默认值形参z可设默认值Y,z可设默认值Fun(int x , int y=4,int z=5);X,y,z都可设默认值c. 说明:默认值自右向左缺省,使得主调函数在表示实参时,不出现空实参。若函数在程序中,只有定义没有声明,将默认值表示在形参中。若函数在程序中,既有声明,又有定义,将默认值表示声明中,定义里就不再写了。5、 函数重载在c+程序中,允许出现多个同名函数。要求:函数在参数个数不同,参数类型不同,仅有返回值不同是不够的。注意:函数在重载时不允许出现调用的二义性。例:IntMax(int x,int y)Returnx y ? X : y;Double Max(double x,double y)Return x y ? X : y;Int Max(int x, int y, int z)Return x y ? X : y;6、 构造函数1. 构造函数相关说明构造函数是类的公有成员函数。使用构造函数的目的在于:在创建类的对象时,通过类的构造函数,完成对类的私有数据成员的初始化。构造函数可以在类内也可以在类外实现。若在类外实现,必须加类的作用域。2. 构造函数的特点构造函数的函数名与类名同名构造函数在调用时,由系统自动调用,在程序中每创建一个对象,都由系统为这个对象调用构造函数,完成这个对象的初始化。=在程序n(创建的对像数)=n(调用构造函数的次数)构造函数没有 返回值类型。注意:区别于void无返回值类型。Void也是一种返回值类型。Class myclassInt x,y,z;Public:/创建对象时必须调用构造函数,完成初始化Myclass(int xx,int yy)/构造函数X = xx;Y = yy;Myclass my(3,4);说明:分配单元描述初始化值(不需要显示调用)。创建myclass(3,4)类的对象my1;系统为对象my1分配存储单元This指针指向对象my1调用对象my2的构造函数,传递实参(3,4),完成构造注:构造函数可以重载,也可以设置默认值。创造对象时,若无参构造,则对象后可缺省();3. 将构造函数在类外实现在类内要对构造函数进行声明,类外实现时,要加类的作用域。Class myclassInt x,y;Public:Myclass(int x,int y);/加声明;Myclass:myclass(int xx=0,int yy=0)/加类的作用域X = xx;Y = yy;当构造函数有默认值并且在类外实现,将默认值声明在类内的构造函数的声明中。注:每个类都必须定义构造函数,用来完成对象初始化。在定义类时,若未定义构造函数,系统将自动生成无参无语句的空构造函数。例题:构造函数#includeusing namespace std;class test int num; public: test(); test(int);test:test() cout init default endl; num = 0;test:test(int n) cout init y ? X : y;Int max(int x ,int y,int z = 9)/errorIf (x y)Return x z ? X : z;ElseReturn y z? Y :z;myclass(int a)/error,析构函数无参Vlaue = a;Private:Int value;Int main(void)Myclass my;My.max(10,20);/error二义性Return 0;注意:Int max(int a, int b);Char max(char a,char b);/字符不参与运算,字符要参与运算,转为int。同样float与double 一样。所以这种情况不满足重载条件参数类型不同4. 动态对象的使用必须用delete释放,无法自动调用析构函数创建类的一个动态对象,并将地址存入指向类的对象的指针变量。类名 * 指针变量; /创建动态对象,使指针指向该对象。指针变量 = new 类名;若该动态对象在类外定义,很明显,我们无法完成该对象的初始化(无法访问私有成员),所以创建该动态对象时,系统将会自动为该动态对象调用构造函数 ,完成该动态对象的初始化。有参构造指针变量 = new 类名(实参值);无参构造指针变量 = new类名;由new分配的动态对象,必须用delete释放。Delete 指针变量。由delete释放对象时,系统将自动调用该对象的析构函数。例:#includeusing namespace std;class myclass int x,y; public: myclass(int a=0,int b=0) x = a; y = b; myclass() cout destorying 在程序运行结束时,系统自动调用析构函数。3. 全局对象的构造函数全局对象在创建时,也需要调用构造函数完成初始化。=全局对象在编译阶段,定义时,调用构造函数,完成全局对象的初始化。全局变量在编译阶段分配单元 & 函数内的局部变量在运行时分配单元9、 C+中构造函数的调用先调用全局对象的构造(编译阶段),再调用局部的(运行阶段);若有多个全局对象,按定义顺序调用构造;若有多个局部对象,按运行顺序调用构造;动态分配的对象则看具体代码。析构函数调用顺序严格与构造函数调用顺序相反。10、 友元函数说明:不是类的成员函数,属于普通函数=友元函数不能使用对象调用,但在友元函数中可以使用对象。在友元函数中一个对象可访问自己的私有成员。友元函数的定义就是一个普通函数,在类内将该函数声明为类的友元函数。友元函数在类内的声明 Friend 数据类型 友元函数名(形参表);上述的第二个程序用友元表示:添加友元声明:friend int sum(myclass a,myclass b,myclass c);函数定义改成:int sum(myclass a,myclass b,myclass c)Return a.x + b.x + c.x;调用语句改为:Sum(my1,my2,my3);Friend 关键词只在类内声明友元函数时使用。注:友元函数慎用(破坏类的封装)例题:完成一下类的实现:Class myclassPublic:myclass()x=0;Friendint getnum(myclass my);Private:Int x;则在main()中Int getnum(myclass my)Return my.x; /key11、 类的静态成员类的静态数据成员属于类的成员而非对象的数据成员。一个类无论定义多少个对象,所有对象共享同一个数据成员静态数据成员注:一个类中可以有两种数据成员 非静态 和 静态1. 非静态数据成员在类中的定义的普通数据成员:通过类创建的每个对象都拥有类的非静态数据成员=对象在分配单元时,对象单元由所有的类的非静态数据成员组成。非静态数据成员属于对象,而不属于类本身。2. 静态数据成员属于类不属于对象。创建对象时,单元中不没有类的静态成员。属于数据成员=受访问权限的限制。类内声明,类外定义初始化。静态数据成员的声明和初始化声明:在类中静态数据成员前加入关键词static注意:静态数据成员必须在类内声明,在类外定义。Static成员不是通过类的构造函数进行初始化,而是应该在定义时进行初始化。Static 只在类内声明时使用。类外初始化:(静态数据成员必须在类外初始化)数据类型 类名:静态数据成员=初始化值;例:Class myclass Int x,y;/非静态数据成员Staticint k;/静态数据成员;Int myclass: k=0;/静态数据成员必须在类外初始化。Int main()Myclass my1,my2;说明:在运行阶段为对象my1分配单元,my1的数据成员x,y。又对my2分配单元,my2的数据成员x,y。注:在编译阶段就为类的静态数据成员分配了存储单元并初始化。类的静态数据成员在类外调用时必须加上类的作用域。静态成员函数类的静态数据成员也受访问权限的控制。若静态数据成员设有私有权限,则类外只有友元可以访问。静态数据公有时,对象也可以调用。对象.静态数据静态成员函数属于类的成员函数=属于类而不属于对象=静态成员函数不可以通过对象调用。声明Static 数据类型 静态成员函数名(形参表)函数体静态成员函数的调用类外类名:静态成员函数(实参表)作用:在函数体中处理静态数据成员。将静态数据成员私有化=类外不可访问静态数据成员。将静态数据成员函数公有化=类外可以访问静态数据成员函数。(不可以用对象访问)在类外直接调用静态成员函数(公有),通过静态成员函数处理类的静态数据成员。静态成员函数可以应用非静态数据,但其不是通过对象调用。所以,无法用this指针指向非静态数据=在静态成员函数中,无法用对象来调用非静态数据。对象.静态成员数据系统在读该对象,找不到这个成员数据,就去找静态数据。原则上:在类的静态成员函数中,不可访问类的非静态数据成员(this 指针造成只可使用静态成员)实际上,在静态成员函数中,也可通过对象去引用类的非静态数据成员。12、 引用运算1. 引用:给一个变量起别名给一个存储单元重命名关键词: &说明:数据类型 引用符 引用名=变量名;注意:引用名所引用的变量必须事先存在。引用名所引用的数据类型必须和变量的数据类型保持一致。例题:Int x = 3;Int &ref = x;/引用Cout x endl;/print 3Cout ref endl;/print 3X+=4;Coutref在被调函数中,通过可用引用主调函数中的变量。(相比于使用指针,使用引用少用一个存储单元)。例题:任意输入两个整数x,y,通过fchange实现x,y值的互换#includeusing namespace std;int main() int i = 10; int j = 20; int &v1 = i; int &v2 = j; cout befor swap():ti: i tj j endl; swap(v1,v2); cout after swap():ti: i tj j i;/this is used to stop the windows for watching the datareturn 0;void swap(int &v1, int &v2 ) int temp = v1; v1 = v2; v2 = temp;3. 使用引用的优点通过引用在被调函数中可改变主调函数变量的值。使用引用节省内存资源。4. 常量引用声明: Const 数据类型引用 引用名=变量名;引用是一个常量,引用的是变量不可通过常量引用去改变常量引用所引用的变量单元。例题:Int x = 3;Int &ref1 = x;Const int &ref2 =x;X = 5;/trueRef1 = 8;/trueRef2 = 5;/error用途:若变量需要引用且同时不允许通过引用来修改变量的值。13、 拷贝构造函数1. 特点:拷贝构造函数是一个构造函数属于类的成员函数;访问权限:公有 public;和类名同名;和构造函数进行重载;2. 何时调用拷贝构造函数通过类创建对象时,若正在创建的对象初始化值是一个已存在的同类对象。那么就要为正在创建的对象调用拷贝构造函数。=若有一个对象在创建时,初始化值是另一个对象,就要调用拷贝构造。3. 声明类外的:类名作用:类名(const 类名 &引用名);例题:#includeusing namespace std;class myclass int x,y;public: myclass(int a=0, int b=0) x = a; y = b; /* myclass(const myclass &t) /call copy constructor x = t.x + 1; y = t.y + 2; */ void print() cout x : x y : y endl; myclass(const myclass &t);myclass:myclass(const myclass&t) cout copy constructor x;return 0;拷贝构造函数只有一个参数,并且参数为一个对象的常量引用。每个类都必须有一个拷贝构造函数,若在程序中没有定义,则系统会自动建立一个拷贝构造函数。在函数调用中,若形参是一个对象的定义,而实参是一个对象。系统为形参分配单元,然后调用形参对象的拷贝构造函数将实参对象初始化。14、 类的继承继承的定义:在创建一个新类时,正在创建的类共享了一个已类的全部特征。这个过程称为继承。注:继承可提高软件的开发效率,提高软件的可重用性。新类(子类)继承了已有类(父类),已有类派生新类继承是发生在类与类之间,分三种方式继承。子类在继承时,必须继承父类的所有特征,但不继承构造函数和析构函数。子类构成:由父类继承而来的特征 + 自己新建的特性继承是单向的单一继承在创建子类时,子类只从一个父亲继承。1. 子类定义:Class子类名:继承方式 父类名注:在子类类体中,只声明子类自己的新特性。2. 继承方式:子类在继承父亲成员时,对父类成员的访问权限。 Public 公有继承:子类以公有的方式继承父类所有的特性基类的公有成员和受保护成员在派生类中保持原状态。(即在派生类中还是公有,受保护的)基类的私有成员在派生类中依然私有,但不可见。(注意查看子类成员时,可对比父类成员)3. 访问对基类对象而言,只可访问基类的公有成员在基类内部,公有成员可访问私有成员。派生来的对象可访问派生类自己定义的公有成员,不可以访问派生类自定义的私有和受保护成员。(与普通的类的对象一样)派生类对象对基类:派生类对象可以访问基类公有成员。派生类类内:派生类公有可访问基类的公有,受保护。综上:派生类对象可访问派生类公有成员和基类的公有成员。派生类类内可访问基类的公有成员和基类的受保护成员。基类对象可访问基类的公有成员。基类类内公有成员可访问基类私有成员。例题:#includeusing namespace std;class A public: void fun1(int a) cout a = a endl; void fun2(int b) cout b = b endl; ;class B: public A public: void fun3() cout its inclass b x;return 0;程序说明:派生类对象g先在派生类中,查找是否有成员fun1.如果有,则调用派生类成员。如果没有,再在基类中。4. 构造函数和析构函数不继承:派生类在继承时,不继承基类的构造和析构函数。基类对象在创建时,只调用基类构造,派生类对象在创建时,先调用基类构造,完成派生类对象中从基类继承来的数据成员的初始化。再调用派生类的构造函数,完成派生类对象中派生类自己的数据成员的初始化。一个派生类对象的单元组成:从基类继承的数据成员+派生类自定义的数据成员。#includeusing namespace std;class A private: int ia;public: void fa( ); A( ) ia = 10; ja = 11; cout ia = ia t ja = ja endl; protected: int ja;class B : public A public: void fb( ); B( ) ib = 20; jb = 21; cout ib = ib t jb = jb endl; protected: int jb ;private: int ib;class C : public B private: int ic;public: void fc( ); C( ) ic = 30; jc = 31; cout ic = ic t jc = jc x;return 0;注:基类中的私有数据成员被派生类继承但不可访问。派生类对象单元中基类的私有数据成员必须通过基类的构造函数完成初始化。5. 派生类调用构造函数派生类对象在创建时必须调用派生类构造函数 =在派生类构造函数中一定要表示对基类构造函数的调用。a. 派生类构造函数的定义派生类名(总形参表):基类名(实参表)派生类构造函数的函数体派生类名(总形参表)b. 调用过程:调用基类构造函数完成对基类数据成员(派生类中)的初始化。基类函数调用完成后,执行派生类构造函数的函数体将派生类对象中派生类的数据成员初始化。注意:派生类构造函数的形参必须表示所有的参数。例题:#includeusing namespace std;class base int x,y;public: base(int xx, int yy) x = xx , y = yy; int getx( ) return x; int gety( ) return y; ;class derived : public baseprivate: int z;public: derived(int a=0, int b=4) : base(5,6) /表达式的含义是,要构造时,需要什么才可以完成初 cout a = a endl; /始化 cout b = b endl; int print(int a=4, int b=6) cout a = a endl; cout b = b end

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论