C++程序设计基础教程.ppt

上传人:1595****071 文档编号:71452812 上传时间:2023-02-03 格式:PPT 页数:346 大小:2.26MB
返回 下载 相关 举报
C++程序设计基础教程.ppt_第1页
第1页 / 共346页
C++程序设计基础教程.ppt_第2页
第2页 / 共346页
点击查看更多>>
资源描述

《C++程序设计基础教程.ppt》由会员分享,可在线阅读,更多相关《C++程序设计基础教程.ppt(346页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、第二期更新内容C+11/14C+11/14标准标准Lambda、static_assert,type traits,Move semantics。WIN32 WIN32 消息,绘图,控件,资源,文件,内存,进程,线程。消息,绘图,控件,资源,文件,内存,进程,线程。起源语言特点语言缺点C+语言及相关软件介绍day01前景与方向编译器安装与配置由C+起源:1974年Bjarne博士在分析与研究UNIX系统由与内核分布面造成的网络流量时试图寻找一种有效工具使其更加模块化他在c的增加了类似Simula的类的机制并与1983年开发一种新的语言C+;C+的语言特点1兼容c且继承了c的特性并同c一样高效且

2、可移植2属于面向对象的编程抽象封装继承多态3语言灵活(类的层次结构设计)且支持指针3支持运算符重载4异常处理机制5支持泛型编程Tf(Tx)returnx*x;6多种类库的支持语言缺点:语言复杂支持多种设计风格复杂的c+程序正确性不易保证C+的发展方向windows平台unix平台嵌入式C+也是一种编译型的语言推荐使用vs2013编译环境其他可选vc6.0vs2010nodepad+vs2013基本支持c11标准vs2010以上Vs2013是微软公司的一款软件开发平台IDE(集成开发环境)Vs2013的安装使用1安装前需要先安装IE10提供支持2下载安装包http:/ inline 一种新的嵌套

3、名字空间的使用方式嵌套在名字空间的内联名字空间在使用时不需其名字空间进行限定使用Inline namespace inspace 布尔类型string类型结构体数据类型day04联合枚举1新的数据类型:布尔类型:bool表示布尔量的数据类型取值:由字面值常量true(非零)真false(0NULLfalse0)构成trueboolisok=true;boolnotok=false;2字面值truefalse可以通过提升转换为int类型true1false0inta=true;/a=1;3任何基本类型都可以被隐式转换为布尔类型转换后非0为真0为假二String类型(类)(自动处理大小)使用需要添

4、加头文件stringC语言中是用字符数组来存放字符串chara110=“abc”a22=a,0;1初始化:stringstr1;stringstr2=“abc”;2String可以做赋值拼接等功能结构体:在c+中结构体内允许定义函数且结构体在计算大小时为1而C中为0在定义结构体时可以省略关键字struct联合:定义时可以省略联合名为匿名联合()访问时可以不用加联合的前缀X.枚举:枚举类型在c+中为一个独立的类型不能把一个整数赋值给一个枚举变量C+11:1 类型的占位符 auto 根据初始化的内容推断变量类型 作用简化代码 2 nullptr std:nullptr_t类型的值,用来指代空指针

5、nullptr和任何指针类型以及类成员指针类型的空值之间可以发生 隐式类型转换,同样也可以隐式转换为bool型.强类型枚举强类型枚举C+11中通过引入了一个称为强类型枚举的新类型,修正了这种情况。强类型枚举由关键字enum class标识。它不会将枚举常量暴露到外层作用域中,也不会隐式转换为整形,并且拥有用户指定的特定类型(传统枚举也增加了这个性质)函数重载(函数多态)重载机制哑元函数函数重载一day051概念:同一作用域的一组参数列表不同,函数名相同的函数这组函数叫函数重载(C+允许定义相同名称的函数)作用:重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污

6、染,对于程序的可读性有很大的好处(一物多用)参数列表不同:1参数类型不同2参数顺序不同3参数个数不同重载版本根据参数的匹配度进行选择注意:1.1与函数参数的变量名无关1.2函数的返回值类型与重载无关2函数重载的实现原理是通过c+换名实现的extern“C”intfun()的形式可以以c的方式生成函数名(无换名机制)3使用场景:当函数基本上执行相同的任务使用不同形式的数据时哑元函数缺省参数内联函数函数重载二day06哑元函数:参数只有类型没有形参名的函数voidfun(int);功能:1保持向前兼容性2做函数的区分Toperator+()Toperator+(int)缺省参数如果函数的形参有缺省

7、值,当函数调用时没有传递实参,那么形参就使用缺省值,如果调用函数时传递了实参,那么形参就使用实参的值注意:1缺省参数靠右原则如果一个函数有多个参数且部分参数有缺省值那么缺省值的参数必须靠右(在编译期间确定参数)2如果函数的声明和定义分开那么缺省参数只能写在函数的声明部分3注意防止重载的冲突(歧义)4c+中函数的规则不接受任何参数(否则可能构成重载)5 凼数参数的缺省值叧能在凼数声明丨指定 3内联:函数使用关键字inline关键字修饰的函数叫做内联函数函数调用过程:调用用后立即存储该指令的内存地址将函数参数复制到堆栈跳到标记函数起点的内存单元执行函数代码(可能还有返回值放入到寄存器中)将返回值弹

8、出然后跳回到地址被保存的指令处内联的实质:就是把函数编译好的二进制代码替换成函数的调用指令(省去了调用开销)(空间换取时间)注意:1类中直接定义的函数自动被处理成内联函数,所以一般把内联函数放在头文件中2inline是一种请求,实现方式取决于编译器,特别是当函数较大或是递归的时候1引用的概念2如何创建一个引用3引用的本质指针与引用day074引用的应用5引用与指针1引用:引用是已定义变量的别名,为c+新增的一种复合类型2创建一个引用:intvar_i;int&int&revar_i=var_i;注意:1这里的&不是取址符而是类型标识符的一部分2创建引用时必需初始化3引用的内容不能为空null4

9、引用创建之后就不能更换引用的内容int&ra=a;ra=b;这样定义之后我们就可以用var_i或rvar_i来操作变量var_i;3引用的本质:引用的内部是由指针完成实现的int*double*其本身并非一个实体类型(可由sizeof证明)int&double&4引用的应用:4.1做函数的参数省去函数参数进行复制时的内存开销常引用型的参数可以防止实参被无意修改且可以接受常量型与非常量型参数foo(constint&i)I=0foo(a)4.2做函数的返回值做返回值时需保证返回值的有效性注意:不能返回局部变量的引用也可以返回常引用型的返回值补充:左值与非左值(右值)一般的左值参数是可以被引用的数

10、据对象如:变量数组元素结构成员引用和解除引用的指针都是左值非左值包括字面常量(引号括起的字符串除外,它们由其地址表示)和包含多项的表达式intI;I=10;10=I;strings1=s2+s3+s4;(a+)临时变量temp(a+1),右值intc=(a+b)右值;“abc”=“abc”(+a)=1;左值int&I=10;右值引用5指针与引用5.1指针是一个实体存放地址而引用仅是一个内存的别名5.2引用必须初始化且初始化后不可更换其引用的目标指针可以不初始化且其指针的指向的内容可随时更换(常指针除外)5.3引用不可以为空指针可以为空/char*pc=0;char&rc=*pc;.5.4引用的

11、大小为所引用变量的大小指针为4个字节5.5因引用是一个内存的别名所以不存在引用引用的引用和引用数组但存在指向指针的指针和指针数组5.6在使用时,如果你的变量的指向可能发生变化或为空,请使用指针,如果你的变量不允许为空,可以引用5.7 不存在空引用的事实意味着引用的代码比指针的代码效率要高 (无需检查其他合法性)5.8 重载某些运算符时,必须用到引用做返回值C语言的类型转换C+的类型转换Static_cast类型转换day08Const_castReinterpret_castC+提供丰富的不同的数据类型当不同类型在进行算术运算参数传递等一系列的操作时因计算机的特性不得不将不同的类型进行转换后再

12、进行操作1初始化和赋值进行的转换(int)dint(d)=右边的类型将会转换成左边的数值类型(赋值后的数值不安全)2以方式初始化时进行的转换(不允许缩窄浮点转换整型)(c+11)3表达式中的转换类型提升4传递参数时的转换5强制类型转换5.1(typename)value:标ctypename(value):c+5.2static_cast(源类型变量)a-b隐式类型转换的逆转换转换时做静态检查(在编译时进行)检查(诸如指针越界计算,类型检查)Char-intIntchar5.3const_cast(源类型变量)去除指针或引用上的const属性voidfoo(constint*i)5.4rein

13、terpret_cast(源类型变量)任意类型的指针或引用或整型之间的转换但不可改变const属性其他限制是不能转换成比指针更小的类型不能将函数指针与其他类型进行转换5.5dynamic_cast(源类型变量)多态父子类指针或引用之间的转换动态转换New的使用方法Delete使用方法Lambda表达式动态内存分配/lambda表达式day09C+在添加动态分配运算符newdelete的同时,支持标准C的动态分配库函数语法:1type_name*pointer_name=newtype_name;/未初始化说明:与malloc不同new会根据类型的不同自动分配对应的内存大小且返回对应类型的指针2

14、type_name*pointer_name=newtype_name(value)/初始化3type_name*pointer_name=newtype_name()/初始化为零4type_name*pointer_name=newtype_namen分配n个type_name的数据的内存大小4type_name*pointer_name=newtype_namen=1,2,3,4.c+0 x标准初始化数组时进行初始化5deletepointer_name与非new配对使用6deletepointer_name与new配对使用某些编译器在分配数组的大小时会在所分配的内存前多加4个字节大小用于

15、存放分配的数组大小7对new分配内存是否失败的判断new操作符会抛出bad_alloc异常C+之父给C程序员的建议1.1尽量的少使用宏使用inline函数替代带参的宏使用constenum去替代常量宏1.2使用namespace去避免命名冲突1.3变量随时用随时定义以保证初始化1.4尽量少使用强制类型转换如果必须转换就使用四个转换运算符中的一个1.5少使用mallocfree因为newdelete会做的更好1.6尽量少使用C风格的字符串因为string会使用更方便1.7逐步建立面向对象的思想Lambda 表达式”(lambda expression)是一个匿名函数,即没有函数名的函数。Capt

16、ure 子句子句Lambda 可在其主体中引入新的变量(用 C+14),它还可以访问(或“捕获”)周边范围内的变量。1.var表示值传递方式捕捉变量var;2.=表示值传递方式捕捉所有父作用域的变量(包括this);3.&var表示引用传递捕捉变量var;4.&表示引用传递方式捕捉所有父作用域的变量(包括this);5.this表示值传递方式捕捉当前的this指针。空 capture 子句 指示 lambda 表达式的主体不访问封闭范围中的变量。可以使用默认捕获模式(标准语法中的 capture-default)来指示如何捕获 lambda 中引用的任何外部变量(使用 capture-defa

17、ult 时,只有 lambda 中提及的变量才会被捕获)注意事项:引用捕获可用于修改外部变量,而值捕获却不能实现此操作。(mutable允许修改副本,而不能修改原始项。)引用捕获会反映外部变量的更新,而值捕获却不会反映。引用捕获引入生存期依赖项,而值捕获却没有生存期依赖项。当 lambda 以异步方式运行时,这一点尤其重要。如果在异步 lambda 中通过引用捕获本地变量,该本地变量将很可能在 lambda 运行时消失,从而导致运行时访问冲突。参数列表参数列表在 C+14 中,如果参数类型是泛型,则可以使用 auto 关键字作为类型说明符。这将告知编译器将函数调用运算符创建为模板。参数列表中的

18、每个 auto 实例等效于一个不同的类型参数。可变规范可变规范通常,lambda 的函数调用运算符为 const-by-value,但对 mutable 关键字的使用可将其取消。它不会生成可变的数据成员。利用可变规范,lambda 表达式的主体可以修改通过值捕获的变量返回类型返回类型将自动推导 lambda 表达式的返回类型。无需使用 auto 关键字,除非指定尾随返回类型。trailing-return-type 类似于普通方法或函数的返回类型部分。但是,返回类型必须跟在参数列表的后面,你必须在返回类型前面包含 trailing-return-type 关键字-。如果 lambda 体仅包含

19、一个返回语句或其表达式不返回值,则可以省略 lambda 表达式的返回类型部分。如果 lambda 体包含单个返回语句,编译器将从返回表达式的类型推导返回类型。否则,编译器会将返回类型推导为 voidLambda 体体从封闭范围捕获变量,如前所述。参数 本地声明变量 类数据成员(在类内部声明并且捕获 this 时)具有静态存储持续时间的任何变量(例如,全局变量)面向对象抽象类与对象类与对象day10C+是一种面向对象的编程语言面向对象(oop)是一种特殊的设计程序的概念性方法C+的一些语言特性使得应用这种方法更容易OPP特性:抽象封装继承多态代码重用1抽象:现实空间逻辑抽象计算机学生学生类ST

20、UDENT学生:属性:stringname;stringmajor;doublescore;行为:voidstudy();voidexam();voidplay();2类:具有相同的属性和行为的对象被分成一组即为一个类类在c+中为一种自定义复合类型:成员变量成员函数(方法)3对象:类是对现实世界的抽象对象则是类在程序中的一个虚拟的实例可以用类来声明变量(也称为实例)。每个实例是类的一个对象4使用类来描述一个类struct/classSTUDENT访问控制限定符:/struct无stringname;intstuID;doublescore;voidstudy();voidexam();void

21、play();5实例化:定义类的实例可以称为类的实例化STUDENTstudent;6struct定义类成员默认为公开class定义类成员默认为私有7成员控制限定符public:公有成员任意访问protected:保护成员只有本类成员和子类可以访问private:私有成员只有本类成员可以访问对不同成员的访问控制属性加以区分体现了c+作为面向对象程序设计语言的封装特性8类的声明与实现可以分开(分开后则不能形成内联)如何初始化对象创建过程对象的创建过程day11如何初始化成员对象?(因为私有成员的存在)C+为类的初始化提供了一个特有的函数-构造函数构造函数的作用:对对象的成员的初始化构造函数的特性

22、:1构造函数与类型名相同2当创建一个对象时会被自动调用(仅调用一次)3构造函数没有返回值类型4.1如果不提供构造函数编译器则自动提供一个无参构造函数4.2但提供构造函数编译器会自动回收默认的构造函数4.3缺省构造构造对基本类型不做初始化类类型调用相应的缺省5构造函数可以进行重载6构造函数的参数可以是默认值,但默认值必需靠右编写一般可以通过构造函数参数的默认值简化构造函数的个数对象的创建过程1为整个对象分配内存空间2以构造实参调用构造函数2.1构造基类部分(无基类忽略)2.2构造成员变量(如果是类类型则构建这个成员)2.3执行构造代码(函数只放在代码区)3在栈中创建单个对象类名对象;/注意不加空

23、括号Aa;类名对象(实参表)4在栈中创建对象数组类名对象数组元素个数类名对象数组元素个数=类名(实参表),;类名对象数组=类名(实参表),;A*arr10=newA10A(1),A(2);实现一个时钟类初始化列表类型转换构造拷贝构造初始化列表,析构,单参构造函数day121构造函数的初始化列表A(inti):.i(i).,.m_i=i;与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段2为什么使用初始化列表初始化类的成员有两种方式,一是使用初始化列表,二是在构造函数体内进行赋值操作/2.1常量成员,因为常量只能初

24、始化不能赋值,所以必须放在初始化列表里面2.2引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面2.3成员变量的初始化顺序:按照成员定义的顺序进行初始化(与初始化表的顺序无关)2.4类的类型成员变量和基类子对象必须在初始化列表中初始化,否则将调用相应类型的缺省构造函数进行初始化(数组成员不能在列表中初始化)3类型转换构造函数(单参构造函数)构造函数当其参数只有单个时它还有另一种功能:类型转换3.1在目标类型中,可以接受单个源类型对象实参的构造函数,支持从源类型到目标类型的隐式类型转换classAA(inti,intj=0,)Aa=100;3.2通过explici

25、t关键字,可以强制这种通过构造函数实现的类型转换必须显式地进行4析构函数4.1析构函数形式:类名()4.2特点:无返回值,无参数,且不能重载4.3何时被调用:在销毁对象时,会自动调用,且仅被调用一次(也可手调用)4.4应用:一般用于对对象在构造过程或生命周期内所申请的资源内存也可以执行其他类设计者所需要的最后使用对象之后的操作(如没有动态分配内存,非必需定义析构函数)4.5缺省析构函数5.1如果类中没有定义析构函数,编译器会提供一个缺省析构函数5.2缺省析构函数的特性:5.2.1对基本类型的成员变量不做任何操作5.2.2对类类型的成员变量和基类子对象,会调用相关的类型的析构函数6对象的销毁过程

26、6.1调用析构函数:执行析构函数,析构成员变量,析构基类部分6.2释放整个对象所占用的内存空间This指针常对象This指针与const关键字day131this指针1.1概念:指向当前对象类型的指针1.2构造函数中this代表正在“被”构建的对象的地址Aa;this=&a;1.3在成员函数中this代表调用这个函数的对象的地址注意:Ithis是由编译器自动产生的,在类的成员函数中有效IIthis是一个常量,不允许对其赋值。III当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数IVthis指针并不是对象本身的一部分,不会影响sizeof的

27、结果2this指针的应用2.1区分当一个类的某个成员变量与该类构造函数的相应参数取相同标识符,在构造函数内部可以通过this指针将其区分2.2做函数的参数2.3做函数的返回值(串连调用)3常对象3.1概念:用const修饰的对象叫常对象3.2作用:被const修饰的对象的数据成员不可以被改变3.3格式:const对象名或const对象名const*常对象指针名const&常对象引用名注意:一常对象只能调用(常函数(不可在常函数内修改成员变量,其实修饰的是this指针,除非在成员函数被mutable(只能修饰成员变量)二非常对象可以调用(常函数)与(非常函数)三原型相同的成员函数的常版本与非常版

28、本可构成重载(匹配原则是:常对象只能选择常版本非常对象优先非常版本)常成员函数含义:通过该函数只能读取同一类中的数据成员的值,而不能修改它常成员函数可不可以修改类外的变量?析构函数静态成员拷贝函数与静态成员day144拷贝构造函数4.1函数形式:class类名类名(const类名&that);4.2用于从一个已定义的对象构造其同类型的副本Ab=a4.3如果一个类没有定义拷贝构造函数,那么编译器会为其提供一个缺省拷贝构造函数(浅拷贝)4.3.1缺省拷贝对基本类型成员变量,按字节复制4.3.2缺省拷贝对类类型成员变量和基类子对象,调用相应类型的拷贝构造函数4.3.3如果自己定义了拷贝构造函数,编译

29、器将不再提供缺省拷贝构造函数,这时所有与成员复制有关的操作,都必须在自定义拷贝构造函数中编写代码完成(深拷贝)4.3.4若缺省拷贝构造函数不能满足要求,则需自己定义4.3.4拷贝构造的时机4.3.4.1用已定义对象作为同类型对象的构造实参4.3.4.2以对象的形式向函数传递参数intfun(Ai);Ai=a;4.3.4.3从函数中返回对象4.3.4.4某些拷贝构造过程会因编译优化而被省略注:所有系统定义的构造函数,其访问控制属性均为公有(public)A;二静态成员static7.1静态成员属于属于类而不属于不属于对象象/受类的访问属性限制的全局属性限制的全局变量或函数量或函数特性:1静态成员

30、变量不包含在对象实例中,生命期为整个程序2静态成员函数无this指针与常属性/3静态成员与其他成员一样受访问控制的限制7.2静态成员的定义与初始化静态成员只能在类的外部进行初始化Aa1a2staticinti;7.3所有该静态成员变量所属的类的对象共有静态成员7.4访问属性1静态成员函数只能访问静态成员2非静态成员函数可以访问静态成员也可以访问静态成员3不使用对象也可以直接使用静态成员静态成员可以看成是受类的访问属性控制的全局变量或全局函数设计模式:单例模式day15一单例模式:一个类只有一个实例(任务管理器),而且自行实例化并向整个系统提供这个实例(最常用,最简单的模式)二根据实例化对象的时

31、机的不同分为两种:1饿汉式:程序启动便创建实例/2懒汉式:调用时创建三优点:1内存中只有一个实例,节约内存2避免频繁创建销毁对象,提高性能3线程安全成员指针day161成员指针:是用于对类中成员进行操作1.1定义格式:成员类型类名:*指针名=&类名:成员名intA:*pi;1.2使用形式:对象.*成员变量指针A*pa=newa;pa-*pi;对象指针-*成员变量指针1.3与普通指针的区别:普通指针用确定对象的地址进行初始化,指向一个确定的对象成员指针用类的成员(是类的成员,而不是对象的成员)初始化(其本质是记录了特定成员变量在对象实例中的相对地址,再解引用时,根据调用对象的地址计算出成员变量的

32、绝对地址)2成员函数指针2.1定义格式:返回类型(类名:*成员函数指针)(形参表);成员函数指针=&类名:成员函数名;2.2使用格式:(对象.*成员函数指针)(实参表)(对象指针-*成员函数指针)(实参表)2.3在调用成员函数指针时使用对象或对象指针的原因是传递this指针3静态成员指针(与普通指针并没有本质区别只是多了类的防控属性)3.1定义格式类型*静态成员变量指针静态成员变量指针=&类名:静态成员变量3.2使用形式*静态成员变量指针返回类型(*静态成员函数指针)(形参表);静态成员函数指针=类名:静态成员函数名;静态成员函数指针(实参表)双目运算符友元二元操作符重载day171操作符重载

33、概念:在C+中,允许把已经定义的有一定功能的操作符进行重新定义,来完成更为细致具体的运算等功能,运算符重载和函数重载都为简单的一类多态2重载目的:c+的面向对象的程序设计需要依赖类的特性,运算符重载的使用使类类在使用普通运算符时变的更加容易3双目操作符的表达式:L#Roperator#a+b重载形式(成员函数):L.operator#(R)t1.operator+(TIME&t2)L为调用对象,R为参数对象重载形式(全局函数)::operator#(L,R)operator+(t1,t2);成员函数形式:classLEFTLEFT&operator#(constRIGHT&right);全局函

34、数形式:LEFT&operator#(LEFT&left,constRIGHT&right)4友元函数4.1通过关键字friend,可以将一个全局函数,或另一个类的成员函数,或另一个类声明为某一个类的友元BfriendA4.2友元是一种定义在类外部的普通函数,但它需要在类体内进行说明4.3友元函数可以访问该类中的所有成员4.4友元函数不受类中访问权限限制,把声明放在类中哪里都可以4.5不是必要尽可能少用,因其破坏了面向对象的封装性5友元类5.1如果类B的成员需要频繁访问类A的数据成员,但因为访控属性的限制,只能通过A的public函数进行操作,那么可以将B声明为A的友元类,这样就可以访问A中的

35、未开放的数据成员5.2友元类一个类可以做另一个类的友元类5.3声明方式friendclass类名;5.4注意事项5.4.1友元关系是单向的5.4.2友元关系不能被传递5.4.3友元关系不能被继承自增运算符输入输出运算符一元操作符重载day181单目操作符表达式:#o/o#2重载形式2.1重载形式(成员函数):O.operator#()a.operator+(b)2.2重载形式(全局函数)::operator#(O)a+;2.3前自增减(操作数为左值,表达式的值为左值,且为操作数本身)classA/成员函数形式A&operator#(void);Integeri1;+i1;A&operator#

36、(A&a)/全局函数形式2.4后自增减(操作数为左值,表达式的值为右值,且为自增减以前的值)classA/成员函数形式constAoperator#(int);constAoperator#(A&a,int)/全局函数形式2.5输出操作符:(左操作数为左值的输出流对象,右操作数为左值或右值,表达式的值左操作数本身)coutstudentendl;如果重载以成员函数形式重载操作符,左操作ostream类为标准库提供且无法添加新成员,那么只能以全局形式重载该操作符重载形式(全局函数):ostream&operator(左操作数为左值的输入流对象,右操作数为左值,表达式的值左操作数本身)如果重载以成

37、员函数形式重载操作符,左操作istream类为标准库提供且无法添加新成员,那么只能以全局形式重载该操作符istream&operator(istream&is,RIGHT&right)其他运算符重载day191操作符重载限制1.1无法重载的运算符:作用域限定符(:)成员运算符(.)直接成员指针解引用运算符(.*.-)条件运算符(?:)字符长度操作符(sizeof)类型信息运算符(typeid)强制类型转换运算符(const_cast)1.2重载限制重载后无法改变运算符的优先级与操作数的个数不能重载非c+内置的运算符$newdeletenewdelete智能指针day201智能指针的概念:是对变

38、通指针进行类的封装,当智能指针离开作用域时,利用类的机制对内部的普通指针指向的内存进行管理foo()PA(newA()2作用:/内置类型auto_ptrpa(newA)share_ptrpa-m_i;相对于普通指针,当其离开作用域时指针本身将会释放,但指针指向的内存却因为指针的释放而无法得到释放,而造成内存泄漏。智能指针是封装了普通指针的类类型的对象,当其离开作用时自动执行的析构函数负责了对普通指针指向的内存的释放3智能指针与普通指针的比较3.1智能指针重载了“*”,“-”运算符;3.2一个对象只能有一个指向它的智能指针,而普通指针可以是多个3.3智能指针在做赋值时是以转义的形式实现(非深/浅

39、拷贝赋值)3.3智能指针不能用于对象的数组autoptrAa=bPointerAAoperator*A*operator-return&*this;(*this=A)(&A=A*pa)pa-m_i;概念语法继承方式继承day21访控属性1面向对象的特征:封装,继承,多态2封装:也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏3继承:可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展(类之间是is-a(kindof)的关系)4基类与派生类:4.1基类(父类):被继承的类4.2派生类(子类):继承数据的类5继承的

40、作用:5.1代码复用5.2功能扩展6语法class子类:继承方式1基类1,继承方式2基类2;7继承方式公有继承:public私有继承:private保护继承:protected8公有继承的基本特点8.1访问属性:a子类中可以直接访问基类的所有公有和保护成员b子类中不可以直接访问基类的私有成员8.2名字隐藏:如果子类中有与基类中的公有或保护名字相同的成员,那么子类的名字或隐藏所有基类中的同名成员如果使用子类或通过子类访问基类的被子类隐藏的成员可以利用:进行调用9继承方式与访问控制因为子类的继承方式的不同,子类对访问基类时的访问控制属性也会发生变化基类中公有子类保护子类私有子类-公有成员公有成员保

41、护成员私有成员保护成员保护成员保护成员私有成员私有成员私有成员私有成员私有成员注意:1子类访问基类成员的最大的权限构造本类成员变量-执行构造代码1.4阻断继承:子类在构造基类子对象时无论如何都要调用基类中的构造函数,如果需要子类无法实例化对象或子类无法被扩展,可以将基类的构造函数的访问属性设定为私有2.1子类析构函数隐式调用基类析构函数子类的析构函数在执行完其中的析构代码,并析构完所有的成员变量以后,会自自动调用其基用其基类的析构函数的析构函数,析构该子类对象中的基类子对象(基基类析构函数不会析构函数不会调用子用子类析构函数析构函数)通过基类指针析构子类对象,实际被析构的仅仅是子类对象中的基类

42、子对象,子类的扩展部分将失去被析构的机会,极有可能形成内存泄漏2.2子类对象的析构过程执行析构代码-析构成员变量-析构基类子对象拷贝构造函数拷贝赋值运算符函数继承中的操作符重载继承中的拷贝构造与拷贝赋值day231拷贝构造函数1.1如果子类未定义拷贝构造函数,拷贝过程中的子类将调用缺省用缺省的拷拷贝构造构造,其会自动调用其基类的拷贝构造函数,构造子类对象中的基类子对象1.2如果子类已定已定义拷贝构造函数,但未未显式指明基式指明基类部分的构造方式部分的构造方式则编译器还是是选择基类的缺省缺省构造函数构造子类对象中的基类子对象1.3如果子类已定义拷贝构造函数,也显式指明了其基类部分以拷贝方式构造则

43、子类对象中的基类部分和扩展部分将一起被复制2拷贝赋值运算符函数2.1如果子类未定义拷贝赋值运算符函数,在触发拷贝赋值时会调用子类的缺省拷贝赋值运算符函数,此函数会自动调用基类的拷贝赋值运算符函数,复制子类中的基类子对象2.2如果子类定义了拷贝赋值运算符函数,但没有显式调用其基类的拷贝赋值运算符函数,则子类对象中的基类子对象将得不到复制2.3如果子类定义了拷贝赋值运算符函数,且显示调用了其基类的拷贝赋值运算符函数,则子子类对象中的基象中的基类部分和部分和扩展部分一起被复制展部分一起被复制3继承中的操作符重载在为子类提供操作符重载定义时,往往需要调用其基类针对该操作符所做的重载定义,完成部分工作方

44、法是:通过将子类对象的指针或引用向上造型为其基类类型的指针或引用,可以迫使针对基类的操作符重载函数在针对子类的操作符重载函数中被调用4私有子类和保护子类类型的指针或引用,不能隐式转换为其基类类型的指针或引用多重继承内存分配名字冲突多重继承day241多重继承:一个类可以同时继承多个父类的行为和特征功能2多重继承的内存分布2.1多重继承中的子类会有多个基类子对象,他们依据继承的顺序由低地址到高地址进行排列2.2构造函数也是由继承的顺序依次构造子类的基类子对象2.3析构函数则与构造的顺序相反3名字冲突overloadnamehideBb;A*pa=&b;pa-fun()在子类的多个基类中,如果在通

45、过子类或在子类中访问多个基类中同名且并未隐藏的标识符时,发有名字冲突。可以通过作用域限定符显式指明所调用的基类标识符或用using指令来解决钻石继承钻石继承的问题虚继承钻石继承day25虚表,虚表指针钻石继承:指一个子类继承自多个基类,且这些基类又继承自相同的基类1钻石继承的问题派生多个中间子类的公共基类子对象,在继承自多个中间子类的汇聚子类对象中,存在多个实例,在汇聚子类中,或通过汇聚子类对象,访问公共基类的成员,会因继承路径的不同而导致不一致2钻石问题的解决方式通过虚继承,可以保证公共基类子对象在汇聚子类对象中,仅存一份实例,且为多个中间子类子对象所共享3虚继承虚继承:继承定义中包含了vi

46、rtual关键字的继承关系虚基类:在虚继承体系中的通过virtual继承而来的基类3.1在继承链最末端的子类的构造函数负责构造虚基类子对象3.2虚基类的所有子类(无论直接的还是间接的)都必须在其构造函数中显式指明该虚基类子对象的构造方式及拷贝方式构造该虚基类子对象,否则编译器将选择以缺省方式构造该子对象;3.3与构造函数和拷贝构造函数的情况不同,无论是否存在虚基类,拷贝赋值运算符函数的实现没有区别4虚表指针汇聚子类对象中的每个中间子类子对象都持有一个虚表指针,该指针指向一个被称为虚表的指针数组的中部,该数组的高地址侧存放虚函数指针,低地址侧则存放所有虚基类子对象相对于每个中间子类子对象起始地址

47、的偏移量多态虚函数函数重写多态day261多态的一般性描述:向不同的对象发送同一消息(函数调用),不同的对象在接收时会产生不同的行为(一个接口,多个方法)foo()(学校校长向社会发布9月1日开学,不同对象的响应)2多态基于系统实现角度分为两类:静态多态性(之前学过的函数重载,运算符重载,编译时决定调用哪个函数),动态多态性(运行时决定调用哪个函数)3虚函数声明形式:virtual返回类型函数名(形参表)注:3.1c+规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数(所以在派生类中的函数可以加virtual也可以不加)3.2只有只有类的成成员函数函数才可以声明为虚函数

48、3.3一个成成员函数被声明函数被声明为虚虚函数后,该类中中不允许有其他与其虚函数相相 同同签名的函数名的函数3.3一个类中,除了构造函数和静构造函数和静态成成员函数函数外,任何函数都可以被声明为虚函数4函数重写:在父子类中子类提供了一个和父类同名的虚函数子类的实现就会把父类的实现覆盖掉(是名字隐藏的一个特例)5多态:当父类型的指针(或者引用)指向子类对象时如果调用虚函数并且子类重写了这个虚函数则调用的表现是子类的否则是父类的本质上去调用哪个成员函数完全由调用者的指针或引用的实际目标对象的类型决定5.1继承是构成多态的基础5.2虚函数是构成多态的关键5.3函数重写是必备条件有效的虚函数数覆盖需要

49、满足如下条件 该函数必须是成员函数,既不能是全局函数也不能是静态成员凼数 该函数必须在基类中用virtual关键字声明为虚凼数 覆盖版本与基类版本必须拥有完全相同的签名,即函数名、形参表和常属性严格一致 如果基类版本返回基本类型数据,那举覆盖版本必须返回相同类型的数据 如果基类版本返回类类型对象的指针或引用,那举覆盖版本可以返回其子类类型对象的指针或引用 如果基类版本带有异常说明,那举覆盖版本不能说明比基类版本抛出更多的异常 无论基类版本位于基类的公有、私有还是保护部分,覆盖版本都可以出现在子类包括公有、私有和保护在内的仸何部分 全局形式重载的操作符函数不能形成多态函数签名:函数名 参数列表

50、常属性函数原型:返回值 函数名 参数列表 常属性纯虚函数与抽象类day271纯虚函数1.1一般声明形式:virtual返回类型函数名(形参列表)=0;1.2作用:纯虚函数无函数体,声明纯虚函数是在基类中为其派生类保留一个函数名字,为派生类根据需要对它进行定义1.3注意:ABfun()如果声明了虚函数,但在派生类中未对其定义,则该虚函数在派生类中仍纯虚函数2抽像类概念:至少拥有一个纯虚函数的类称为抽象类特性:2.1无法实例化对象2.2子类如果不对基类中的全部全部纯虚函数提供重写,则该子类也是抽象类作用:只做为一种基本类型用作继承的类。也称为抽象基类3纯抽象类:全部由纯虚函数构成的抽象类称为纯抽象

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com