c++primar总结.doc_第1页
c++primar总结.doc_第2页
c++primar总结.doc_第3页
c++primar总结.doc_第4页
c++primar总结.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

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

文档简介

浮点数:float 只能保证 6 位有效数字, double 只能保证 10 位有效数字。一般而言,对付典型的比较需要使用大于或小于,而不使用等于或不等于,其根本原因在于计算机对于浮点数的存储方式使浮点数存储精度过低。字面值常量:整形字面值常量默认为 int 或 long ,浮点型字面值常量默认为 double ,字符串字面值常量默认为 C 风格字符串。编写代码时可以利用 将长代码分行,特别对于较长的字面值常量来说,非常管用。初始化:内置类型尽在函数体外定义时被初始化位 0 ,类对象根据构造函数初始化。一般而言,变量在定义时应显示初始化,以避免未初始化的对象被使用。 C+ 对象的初始化分为直接初始化与复制初始化,直接初始化将对变量直接进行初始化,复制初始化将在初始化时先建立一个临时对象,然后调用变量的复制构造函数将临时对象复制给变量。需注意,复制初始化与直接初始化不同,同时,初始化与赋值也不同,需注意区分。例如:int a(10);/ 直接初始化int b=10;/ 复制初始化,先建立一个 int 型临时变量,值为 10 ,然后将临时变量复制给 bint c;c=10;/ 赋值,不是初始化const 限定符:一般字面值常量应该赋值给 const 变量,防止出现魔数。 const 对象默认为文件的局部变量,非 const 变量默认为 extern ,在其他文件中调用时需使用 extern 声明。在遇到 const 限定符时建议从右往左读, const 限定符修饰了的类型就是常类型,例如:const int a=10;/a 为常整型const int *p=&a;/p 为指向常整型的指针int *const q=&a;/q 为指向整数的常指针,该指针不能改变,指针指向的值可以改变,由于此处指向的是常整 数,因此指向的值也不能改变在类中, const 成员变量必须在构造函数初始化列表中进行初始化, const 成员函数中的 const 修饰符改变了 this 指针的性质,该函数只能做读取操作,不能做修改操作,注意从 const 成员函数中返回的值仍为 const 类型。 const 对象(类对象)、指向 const 对象的指针或引用只能调用 const 成员函数,以防止 const 对象被改变。( const 用法较多,此处只是简略说明,更多内容请看 C+Primer )引用:引用必须在定义时初始化,一旦初始化后就不能改变引用对象。引用实际上为被引用变量的别名,两个变量指向同一块内存空间。例如:int a=10;int &b=a;/b 为 a 的引用, a 与 b 指向同一块内存空间int &c;/ 错误c=a;/ 错误typedef :见typedef四个用途和两大陷阱数组:数组中可以存放任意类型的对象。因此可以建立指针数组,多维数组(数组中存储的仍为数组)。数组中对象的初始化遵循常规对象初始化的规则,如引用变量必须在建立时进行初始化,引用数组建立时必须对数组中的所有元素进行初始化。 sizeof 运算符可以求出表达式结果所占的字节数,当表达式为数组名时,可以求出该数组所占的字节数,用 sizeof( 数组名 )/sizeof( 数组类型 ) 时可以求出数组长度。当数组名用于表达式时,数组名转化为指针,这种转化是单向的,即,转化以后该数组名一直保持为指针(但可以继续使用数组的方式使用数组中的元素),转化过后 sizeof( 数组名 ) 值为 4 (指针占 4 个字节)。指针:可以建立指向任意对象的指针,因此可以建立指向指针的指针,指向函数的指针,指向数组的指针等等。指针占用 4 个字节的内存空间,里面存储的是所指对象的地址,即指针存储的是地址。一个有效的指针必然只有三种可能:1 、保存一个特定对象的地址;2 、指向某个对象后面的另一个对象;3 、为 0 值,即 NULL ;未初始化的指针是无效的,使用无效的指针时会出现未定义错误。使用指针指向一个动态对象时,如果一个指针所指的对象已经被释放,该指针应该显示指向 NULL ,否则会出现野指针(指针指向的空间已被释放,但指针内所存的地址没有改变,指针仍然指向该内存空间,其值为任意值)。使用野指针会使程序出现意想不到的错误。如果在某些时候需要用到多个指针指向同一对象,在释放指针所指的对象时需要确保释放最后一个指针时才真正的释放相关内存空间,此时可以使用句柄类或者智能指针达到对指针的控制,避免一个对象被释放多次。引用:可以建立任意对象的引用,因此可以建立指针的引用,例如:Int *a = new int(10);Int *&b=a;/b 是一个指针的引用,引用的对象为一个指针,使用 b 时仍然需要按照指针的方法使用, *b 值为 10 , b 为 b 所指向的内存空间的地址引用常用于函数的形参,函数形参使用地址传递时常使用引用或指针。使用引用可以使函数实参在函数内部被直接改变,减少形参传递时的时间消耗。C 风格字符串:C 风格字符串实质上是字符数组,该数组最后一位为 0 ,字符串字面值常量默认为 C 风格字符串。使用 C 风格字符串时,使用者必须确保目标字符串具有足够的大小,且字符串结束符为 NULL (即 0 )。在使用 C+ 程序时应尽量避免使用 C 风格字符串。复合表达式的优先级:复合表达式的优先级非常重要, C+ 程序员习惯将长代码利用复合表达式的缩短为短代码,如 +p.data; 运算符包括自增运算符与成员选择运算符,成员选择运算符的优先级高于自增运算符,因此,此代码的意思为:首先读取 p 对象的 data 成员变量,然后使 data 成员变量自增一次。 *p+ 的意思为:首先保存 p ,然后使 p 指针自增一次,然后解引用所保存的 p 的值,结果为 p 自增前所指向的对象。类型转换:当实际类型与表达式或函数所要求的类型不同时,实际类型会被隐式(或显示)的进行类型转换。在算数转换时,所有小于整型的类型都会被转换为整型,达到整型仍然不符合要求的类型会被继续提升,直到符合要求为止。 C+ 自动将枚举转换为整型,将用作条件判断的其他内置类型转换为 bool 型,当需要使用 const 类型时,非 const 将被隐式转换为 const 类型。使用类类型时,如果在需要使用类对象时使用了其他类型,但该类型可以成为类构造函数的形参,则编译器会建立一个临时变量,调用类相匹配的构造函数初始化该类。如果类的成员函数中重载了转换构造函数,则该类的对象可以用在任何能够调用匹配隐式类型转换的地方。注意,类的隐式类型转换后只能根有标准库类型转换。当隐士类型转换造成二义性的时候可以使用强制类型转换。标一般强制类型转换使用 static _cast 、 dynamic_cast 、 const_cast 或 reinterpret_cast 操作符。编译器因实质性的任何类型转换都可以由 static _cast 显示完成如:double b=8;char ch = static _cast b;const_cast 可以取消表达式的 const 属性, reinterpret_cast 与 dynamic_cast 不常用,前者用于位运算,后者用于动态类型识别。new 和 delete :new 运算其实分为三个部分,首先调用 operator new 函数分配足够大的为类型化的内存空间以保存指定类型的一个对象,然后运行该对象的构造函数,初始化该对象,最后返回指向新分配内存空间的指针。我们可以通过重载 operator new 函数人为地进行内存分配,达到优化内存的效果。在类中一旦出现重载的 operator new 函数,则系统不再调用标准库的 operator new 函数。 delete 运算使用时分为两个步骤,首先调用指定对象的析构函数,然后调用名为 operator delete 的标准库函数释放该对象所占用的内存。 operator delete 函数同样可以重载。当使用 new 新建一个动态对象以后需要使用 assert 判断动态建立是否成功,以防止程序运行时对未建立的对象进行使用。 delete 数组时需使用 注明。循环:循环的形式主要分为三种,即 for 循环, while 循环以及 do while 循环。理论上来说,三中循环具有等效价值,能够用一种循环书写的代码都能够使用另外两种循环书写。但是在写程序的过程中应当适当区分三种循环的的使用范围, for 循环多用于计数, while 循环多用于当满足一定条件时执行一定结果, do while 循环一般用于限制性后判断循环条件。三种循环区分使用便于程序员阅读代码。函数:函数非引用形参的传递是一个复制的过程。函数调用时,编译器将实参的值复制给非引用形参(包括指针也是如此),然后由形参执行相关操作。函数调用结束后,若函数具有非引用返回值,则编译器将函数返回值复制到函数调用处(在函数调用处建立一个临时变量,将返回值复制给临时变量)。当函数形参或返回值为引用类型,函数形参将成为实参的引用,形参与实参使用同一块内存空间。在 C+ 中能够实现函数重载,即多个函数拥有相同的函数名,不同的函数形参。注意,不能根据函数返回值区分函数是否发生重载(即多个函数拥有相同函数名及形参,不同函数返回值时编译错误)。发生函数重载时,编译器首先根据函数名确定函数的选择范围,然后根据函数形参数目缩小函数候选集,最后根据函数的形参类型在函数的候选集中寻找最佳匹配,若出现唯一的最佳匹配,则发生函数调用,若没有最佳匹配,但根据隐式类型转换后出现唯一的匹配,则发生函数调用,若隐式转换后出现多个匹配,则出现二义性,编译失败。根据函数形参类型选择匹配时,若发生隐式类型转换,则该编译器根据转换等级区分最佳匹配,转换等级降序排列如下如下:1 、精度匹配,即完全匹配2 、通过类型提升实现的匹配,即实参由低精度提升到高精度3 、通过标准转换实现的匹配,即标准库类型转换4 、通过类类型转换实现的匹配,即由用户定义的类型转换高等级的转换相对于低等级的转换总是更好的匹配。当在函数中定义了一个静态变量( static )时,该变量在多次函数调用过程中仅被初始化一次。可以声明指向函数的指针,用于指向具有相同形参与返回类型的函数。指向函数的指针常用于简化函数的调用,或者使用一个指针调用多个函数。标准 IO 库标准 IO 库使用了 ios 作为基类,其余类均直接或间接地派生自 ios 。因此,我们常用的输入输出流均为类的对象。 IO 标准库提供了一系列的函数用于对输入输出流状态进行条件判断,写程序时可以根据条件判断对错误的输入进行抛弃,从而保证结果的正确性。顺序容器:顺序容器分为 vector 、 deque 、 list 三种, vector 类似于我们使用的数组, deque 类似于我们使用的队列,而 list 则是链表。 vector 与 deque 支持快速随机访问,能够使用类似于数组的方式随机访问已存在的任意元素,而 list 不支持该功能。无论是顺序容器,还是关联容器,其元素类型必须满足两个约束:1 、元素类型必须支持赋值运算2 、元素类型的对象必须可以复制由于这两个约束条件的存在,引用类型不能作为容器元素而存在。容器提供一系列的操作使用户在使用容器时能够更方便的得到想要的结果。string 类:string 类常用语对字符串进行保存与修改, string 类提供一系列的操作以便于用户对 string 对象中存储的字符串进行修改。同时用户可以像使用数组一样对 string 对象中的单独字符进行修改,而对象中的其他字符不变,达到随机访问的目的。 string 类支持与 C 风格字符串的相互转化,用户可以用 C 风格字符串赋值给 string 对象,也可以调用 string 对象的 c_str 函数返回 string 对象的 C 风格字符串格式。用户可以直接使用 string 类的成员函数实现对 string 类对象的部分字符进行查找、添加、删除即比较功能。容器的选用需要根据用户常用操作来判断。若用户常用操作为随机访问,则应使用 vector 或 deque 容器,若用户常用操作为在任意位置的添加删除元素,则应使用 list 容器。pair 类:pair 类中包含两个共有数据成员, first 与 second 。用户可以为 pair 类对象自定义数据成员类型,以使 pair 对象满足自己的要求。关联容器中常用 pair 类存储表示两个相关联的变量。如 map 容器使用 pair 类的 first 成员保存键,用 second 成员保存值。关联容器:关联容器分为 map 、 set 以及 multimap 、 mulitset 四种。在使用关联容器时,键需要有一个约束条件,即需要能够被比较,默认情况下,标准库使用键类型定义的 操作符来实现两个键的比较。在键的比较过程中,遵循严格弱序比较,两个键之间只能有小于和相等两种结果。map 容器也被称为关联数组,是键 - 值对的集合,元素通过键来存储和读取相关的值,在 的集合。 set 容器不支持下表操作符,用户在 set 容器中添加获取元素需使用 set 容器的成员函数。multimap 、 multiset 容器与 map 、 set 容器类似,只是单纯的增加了实例个数,在 multimap 容器中,一个键能够对应多个值,同一个键的不同值之间顺序排列,能够通过迭代器的自增或自减实现值得改变。 multimap 容器不支持下表操作符。迭代器:迭代器是一种检查容器内元素并遍历元素的数据类型。每种容器都定义了自己的迭代器类型,一般为:容器类型 :iterator容器常用迭代器对容器内的元素进行遍历,迭代器可以使用解引用操作符对容器内的元素进行读取或改变。部分容器支持迭代器算术操作符以简化迭代器运算。在泛型算法中,常使用流迭代器,反向迭代器进行遍历输入输出流、反向遍历操作。泛型算法使用流迭代器从流对象中读取或写入数据。使用反向迭代器反向遍历元素。插入器个人感觉更像是一个函数。适配器:本质上,适配器是一种是一事物的行为类似于另一事物的行为的一种机制。容器适配器让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现。标准库提供了 queue 适配器实现队列操作,提供 stack 适配器实现栈操作,提供 priority_queue 适配器实现优先级队列操作。泛型算法:泛型算法是指可以在多种容器类型上实现相同操作的一系列函数。每个泛型算法都独立于单独的容器并且只是隐式的依赖于容器存储的元素类型,不同的泛型算法对元素类型的隐式依赖不同,一般来说,泛型算法对容器中元素要求如下:1 、需要某种遍历集合的方式,能够从一个元素向前移动到下一个元素2 、必须能够知道是否到达了集合的末尾3 、必须能够对容器中的每一个元素与被查找的元素进行比较(不同的算法要求的操作符不同)4 、需要一个类型来指出元素在容器中的位置,或者表示找不到该元素可以使用谓词函数实现对泛型函数按照自定义函数进行比较。使用算法写元素时,需要用户自己确保算法所写的序列至少足以存储要写入的元素。由于泛型算法不能改变容器的大小,因此在执行添加或删除容器元素时需要使用迭代器进行操作。泛型算法不改变容器大小,而迭代器改变。数据抽象和封装:类背后蕴涵的基本思想是数据抽象和封装。数据抽象将程序的接口和实现分离,类设计者必须关心类是如何实现的,但使用类的程序员则不必了解这些细节。相反使用类的程序员仅需了解类型的接口,他们可以抽象的考虑该类型做了什么,不必具体的考虑该类型如何工作。封装是一项将低层次的元素组合起来形成新的高层次实体的技术。函数是封装的一种,函数所执行的细节被封装在函数定义中。被封装的元素隐藏了实现细节。类也是一个封装实体,大多数设计良好的类类型隐藏了实现该类型的成员。内联函数:内联函数需要在函数定义处函数返回值前加上 inline (内联说明),编译器在读取到内联说明时会判断该函数是否适合内联,如果不适合则忽略该建议。一般来说,内联函数能够消除函数的额外开销。内联函数会在调用时将函数展开为代码,编译器负责传递参数,然后再调用地点直接执行代码,如果调用地点为表达式,则调用时实现复合表达式的运算。内联函数机制使用云优化小的、只有几行而且经常被调用的函数,大多数编译器不支持递归函数的内联。内联函数应该在头文件中定义,以便多个文件使用。类类的声明只包含类类型关键字和类名,类的定义则包括类类型关键字、类名以及类的全部成员变量声明。类中的成员可以是除类本身的对象以外的任意类型,因此类中的成员可以是另一个类,此处称为局部类。 struct 类与 class 类只在默认访问标识符处有区别, struct 类默认访问标识符为 public , class 类默认访问标识符为 private 。类的成员函数(即函数成员变量)既可以在类定义内定义也可以在类定义外定义,如果在类定义外定义,则定义时需要增加作用域说明,完全限定其作用域。无论成员函数在类定义内还是类定义外定义,都必须在类定义内具有声明。在类内部定义的成员函数会被编译器默认为内联函数,调用该函数时编译器会在调用函数处直接展开函数代码,提高运行速度,但内联函数所具有的约束条件在此处仍然适用。如果成员函数被声明为常成员函数,则在类外定义时仍然需要显示声明该成员函数为 const 。类中的非静态成员函数均带有隐式形参 this* ,该形参指出函数所处的对象,不同的对象调用相同成员函数时,由于 this 指针所指的对象不同,结果也不一定相同。静态成员函数为该类的所有对象共享,调用结果相同。类成员变量在类定义内仅为声明,不能初始化。 const 数据成员可以显示的使用构造函数初始化列表进行初始化,也可以直接在类定义内初始化。类的静态数据成员必须在类的定义体外恰好定义一次。由于静态数据成员被所有该类的对象共享,因此静态数据成员在类定义时被分配内存空间。特殊的,常静态数据成员必须在类内与类外各定义一次,如果在类内部已经被初始化过,则再类外可以不用初始化。静态成员在类外需要通过作用域操作符访问。如果数据成员需要在任何地点(能够访问该数据成员的地方)均能够做出改变,即无论调用该数据成员的对象是否为 const ,无论使用该数据成员的函数是否为 const ,该数据成员都能够改变,则需要将数据成员声明为 mutable 。访问标识符分为三种, public 标识符、 private 标识符、 protect 标识符。 public 标识符是公开标识符,任何使用该类对象的地方都可以访问 public 标识符范围内的成员。 private 标识符是私有标识符,在该标识符范围内被声明的成员只能在类的友元或类本身的成员函数中被访问。 protect 标识符是类对派生类的接口, protect 标识符范围内的成员可以被该类的成员函数、友元以及派生类访问。一般需要派生类知道(访问)而不需要使用类的成员知道(访问)的成员可以声明为 protect 。类的作用域:在类的成员函数中使用的变量首先在该成员函数作用域中查找,如果找不到,则在类的定义体中查找相关变量,如果仍然找不到,则在定义类的文件全局作用域中查找。在类外定义的成员函数,函数的形参表和函数体处于类的作用域范围内,函数返回类型不一定在类作用域范围内。如果函数返回类型为在类中定义的别名,则在类外定义函数时,需要显示指出该函数的返回值处于类作用域。构造函数:如果类的设计者没有自定义类的构造函数,则系统会默认生成一个默认合成构造函数。默认合成构造函数不带形参,仅初始化类类型对象,适用于仅包含类类型数据成员变量的类。构造函数常用来完成对该类对象的初始化工作,可以使用初始化列表完成对部分数据元素的初始化,初始化列表中变量的排列顺序不影响类对象在定义时类中数据成员的初始化顺序,其初始化顺序仅与相应数据成员在类定义中的声明顺序有关。类的设计者可以根据类要实现的功能设计自定义的构造函数,一旦出现自定义构造函数,则编译器不会为该类生成默认合成构造函数。一般而言 , 类设计者定义的构造函数能够进行隐式类型转换 , 例如 :加入类 Screen 具有 string 为形参的构造函数,则void display(Screen &p);display(1234);/OK在上例中,函数调用时,编译器将调用类的构造函数建立一个临时对象,并用字符串 1234 初始化该对象,然后使用临时对象完成函数内部操作。此处完成了一次隐式类型转换。如果类设计者不希望出现构造函数定义的隐式类型转换,则需要将构造函数声明为 explicit ,编译器将不适用该构造函数作为转换操作符。友元:A 类将 B 声明为友元,则 B 可以通过 A 类的对象访问到 A 类的全部成员, B 可以是一个类,也可以是一个函数。友元关系是独立的,类不能通过继承关系继承来自基类的友元,也不能通过派生关系使派生类认同基类的友元。友元关系范围无法通过继承、派生与友元扩大。复制控制:复制控制一般是指复制构造函数、赋值操作符函数、析构函数,一般三者同时需要。如果类的设计者没有自定义复制构造函数与赋值操作符函数,则编译器会生成合成复制构造函数与合成的赋值操作符函数。无论类的设计者有没有定义析构函数,编译器都会生成一个合成析构函数,并在调用完自定义析构函数后运行。合成的复制构造函数只能将指定对象的成员变量的值复制给新对象的相应成员变量,若成员变量中出现指针,则调用合成复制构造函数后会出现两个对象中的某个成员变量指向同一块内存空间,为了避免这种情况发生,类设计者需要自定义复制构造函数,以达到完全正确复制对象的功能。赋值操作符函数功能与复制构造函数功能类似,类的使用者使用类时,如果能够正确使用复制构造函数,则使用者会认为也能够正确使用赋值操作符,因此类的设计者在设计复制控制时,复制构造函数与赋值操作符函数往往需要同时定义。析构函数需要确保类对象在使用结束后能够正确被释放。无论类的设计者是否自定义析构函数,编译器仍然会为类合成默认析构函数。析构函数不仅仅只能做释放工作,也可以做任何类设计者希望类对象在被释放后想做的扫尾工作。操作符重载:在 C+ 中只有作用域操作符( : )、条件操作符( ?: )不能重载。重载操作符既可以作为类的非成员函数,也可以作为类的成员函数,如果操作符重载函数成为类的非成员函数,当操作符重载函数需要调用类的私有成员或保护成员时需要定义操作符重载函数为类的友元函数。操作符重载不能改变操作符的优先级、结合性以及操作数数目,也不能添加用户自定义操作符作为重载的操作符。当操作符重载函数作为类的成员函数时,该函数可以省略第一个形参(默认为 this 指针)。如果类的设计者没有定义对应的操作符重载,则编译器自己定义如下操作符:1 、合成赋值操作符进行逐个成员复制。2 、取地址操作符和逗号操作符,其效果与在内置类型对象上执行一样。3 、内置逻辑与、逻辑或操作符使用短路求值(只有上一个表达式结果使整个复合表达式结果为真时才进行后续表达式求值),如果重定义该操作符会丧失短路求值特性。在设计操作符重载时需要注意:1 、赋值、下标、调用和成员访问箭头等操作符必须定义为类的成员函数,将这些操作符定义为非成员函数将引起编译错误。2 、复合操作符( += 、 -= 、 *= 、 /= )通常应定义为类的成员,但不是一定的。3 、改变对象状态或与给定类型紧密联系的其他操作符,如自增、自减、解引用操作符通常应该定义为类的成员函数。4 、对称的操作符,如算术操作符、相等操作符、关系操作符和位操作符,最好定义为普通非成员函数。自增自减操作符在重载时为了区分前自增 / 后自增与前自减 / 与后自减,类设计者需要使后缀式操作符函数接受一个额外的(无用的) int 型参数,该参数无实际意义,只为区分两种自增自减操作符。可以为类类型对象重载函数调用操作符,函数调用操作符必须声明为成员函数,定义了函数调用操作符的对象成为函数对象。类设计者可以根据函数调用操作符内的形参类型及形参数对函数调用操作符再次进行重载。函数对象常用于通用算法的实参。关于函数对象的更多使用请参照 C+ Primer 第十四章第八节。类型转换操作符重载:类设计者可以设计类型转换操作符重载,用以将类类型转换为需要转换到的类型,该转换过程为隐式类型转换。编译器只能够从类类型转换到相应类型一次,如果需要多次转换则只能跟标准库转换,不能连续多次类类型转换,即不能递归转换。标准转换可以放在类类型转换之前。可以利用类类型转换操作符重载与构造函数实现类类型与内置类型的相互转换。继承与派生:派生类能够继承基类定义的成员,派生类可以无需改变而使用那些与派生类具体特性不相关的操作,派生类可以重定义那些与派生类型相关的成员函数,将函数特化,考虑派生类性的特性。除了从基类继承来的成员以外,派生类可以定义自己特有的成员。基类必须指出希望派生类重定义哪些函数,希望重定义的函数应该被声明为 virtual (虚函数),基类希望派生类继承的函数不能定义为虚函数。基类中的私有成员在派生类中无法直接访问,如果需要访问基类中的私有成员,则派生类需要借助从基类继承来的成员函数。一旦出现派生,则派生类是一个新类,派生类继承了基类的部分成员,但根据基类建立的对象在派生类中没有特殊访问权限。如果在基类中定义了静态成员,则基类与派生类共用静态成员,如果派生类定义有静态成员,则基类无法访问派生类定义的静态成员。友元无法通过派生关系继承。如果一个基类只是作为基类存在,不需要定义对象,并且基类中的部分成员函数在基类中不适用,但是需要在派生类中被重定义,则可以定义该成员函数为纯虚函数。定义有纯虚函数的类称为抽象类,抽象类不能创建对象。每个派生类构造函数除了初始化自己的数据成员之外,还要初始化基类。如果派生类继承自多个基类,则基类的 初始化顺序由派生类派生列表中的基类顺序决定。如果基类没有默认构造函数,则需要派生类在构造函数中显示指出调用基类的哪个构造函数进行初始化。类是否需要定义复制控制成员完全取决于类自身的直接成员,与基类无关。合成的默认复制控制函数会调用基类的复制控制函数对基类进行复制控制。如果派生类定义了自己的复制控制函数,则需要显示指出对基类复制控制函数的调用。在类的继承与派生过程中一般需要定义基类的析构函数为虚析构函数,如果析构函数为虚函数,那么通过指针调用时,运行那个析构函数将因指针所指对象类型的不同而不同。当把一个派生类复制给基类时,将会把派生类中的基类分离出来,只复制基类部分,复制完成后,复制类为基类,因此无法访问派生类部分,也不存在派生类部分。动态绑定:通过动态绑定我们能够编写程序使用继承层次中任意类型的对象,无需关心对象的具体类型。在 C+ 中,通过积累的引用或指针调用虚函数时发生动态绑定。引用或指针即可一直向基类对象也可以指向派生类对象。用引用或指针调用的虚函数在运行时确定。被调用的函数是引用或指针所指对象的实际类型所定义的。基类的指针只能够调用基类部分的成员函数,即使基类引用或指针在运行时指向派生类对象,也只能够执行派生类中基类部分的成员函数。模板:模板是创建类或函数的蓝图或公式。模板形参可以使表示类型的类型形参,也可以是表示常量表达式的非类型形参。使用函数模板时,编译器会推断哪个模板实参绑定到模板形参。一旦编译器确定了实际的模板实参,就实例化了一个函数模板的实例。类类型模板形参表示该类型为未知类,

温馨提示

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

评论

0/150

提交评论