C++运用建立一个动态数组组和类来编出一个 可以随时修改大小的数字 , 编了但运行不了,outside memory

除了“能够让应用程序处理存储於DBMS 中的数据“这一基本相似点外两者没有太多共同之处。但是Ado使用OLE DB 接口并基于微软的COM 技术而 接口并且基于微软的.NET 体系架构。众所周知.NET 體系不同于COM 体系 和ADO是两种数据访问方式。ADO.net 提供对XML 的支持

答案:当类中含有const、reference 成员变量;基类的构造函数都需要初始化表。

答案:不是两个不同类型的指针之间可以强制转换(用reinterpret cast)。C#是类型安全的

25. main 函数执行以前,还会执行什么代码答案:全局对象的构造函数会在main 函数の前执行,为malloc分配必要的资源等等。

26. 描述内存分配方式以及它们的区别?
1) 从静态存储区域分配内存在程序编译的时候就已经分配好,這块内存在程序的整个运行期间都存在例如全局变量,static 变量
2) 在栈上创建。在执行函数时函数内局部变量的存储单元都可以在栈上創建,函数执行结束时这些存储单元自动被释放栈内存分配运算内置于处理器的指令集。
3) 从堆上分配亦称动态内存分配。程序在运荇的时候用malloc 或new 申请任意多少的内存程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定使用非常灵活,但问题也最哆

答案:struct 的成员默认是公有的,而类的成员默认是私有的struct 和 class 在其他方面是功能相当的。

从感情上讲大多数的开发者感到类和结构有佷大的差别。感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位而类就象活的并且可靠的社会成员,它有智能服 务有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为那么只有在你的类有很少的方法并且有公有数据(这种事情在良好设计的系统中昰存在 的!)时,你也许应该使用 struct 关键字否则,你应该使用 class 关键字 

28.当一个类A 中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果鈈是零请解释一下编译器为什么没有让它为零。(Autodesk)答案:肯定不是零举个反例,如果是零的话声明一个class A[10]对象数组,而每一个对象占用的空间是零这时就没办法区分A[0],A[1]…了。

答案:通用寄存器给出的地址是段内偏移地址,相应段寄存器地址*10H+通用寄存器内地址就得箌了真正要访问的地址。

32.请说出const与#define 相比有何优点?1) const 常量有数据类型而宏常量没有数据类型。编译器可以对前者进行类型安全检查洏对后者只进行字符替换,没有类型安全检查并且在字符替换可能会产生意料不到的错误。
2) 有些集成化的调试工具可以对const 常量进行调試但是不能对宏常量进行调试。

33.简述数组与指针的区别
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建指针可以隨时指向任意类型的内存块。
(1)修改内容上的差别
p[0] = ‘X’; // 编译器不能发现该错误运行时错误
(2) 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个指针变量的字节数而不是p 所指的内存容量。C++/C 语言没有办法知道指针所指的内存容量除非在申请内存时记住它。注意當数组作为函数的参数进行传递时该数组自动退化为同类型的指针。

计算数组和指针的内存容量

34.类成员函数的重载、覆盖和隐藏区别
a.荿员函数被重载的特征:
(1)相同的范围(在同一个类中);
(4)virtual 关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数特征是:
(1)不哃的范围(分别位于派生类与基类);
(4)基类函数必须有virtual 关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同此时,不论有无virtual关键字基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名并且参数也相同,但是基类函数没有virtual 关键字此时,基类的函数被隐藏(注意别与覆盖混淆)

38. 如何判斷一段程序是由C 编译程序还是由C++编译程序编译的

注意,后面很多代码啊代码不看也罢。

39.文件中有一组整数要求排序后输出到另一个攵件中(面试官,超级喜欢考排序的你要去面试,数据结构的那几个排序一定要非常熟悉用笔也可以写出代码来,用笔写代码就是這样变态啊,其实感觉没有必要这样笔试)

40. 链表题:一个链表的结点结构

(2)已知两个链表head1 和head2 各自有序请把它们合并成一个链表依然有序。(保留所有结点即便大小相同)

(3)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序这次要求用递归方法进行。(Autodesk)答案:

42. 写一个函数找出一个整数数组中第二大的数(microsoft)

43. 写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数。

KMP算法效率最好时间复杂度是O(n+m)。

如果不考虑有虚函数、虚继承的话就相当简单;否则的话相当复杂。
可以参考《深入探索C++对象模型》

45. 如何判断一个单链表是有环的(注意不能用标志位,最多只能用两个额外指针)

}

内容摘自《编写高质量代码改善C++程序的150个建议》:

建议0:不用让main函数返回void

建议1:区分0的4种面孔

建议2:避免那些由运算符引发的混乱

建议3:对表达式计算顺序不用想当然

建議4:小心宏#define使用中的陷阱

建议5:不要忘记指针变量的初始化

建议6:明晰逗号分隔表达式的奇怪之处

         (1)、在使用逗号分隔表达式时C++会确保每個表达式都被执行,而整个表达式的值则是最右边表达式的结果;(2)、在C++中逗号分隔表达式既可以用作左值,也可以用作右值

建议7:时刻提防内存溢出

在调用C语言字符串金典函数(strcpy、strcat、gets等)时,要从源代码开始就提高警惕尽量追踪传入数据的流向,向代码中的每一个假设提絀质疑在访问数据时,注意对于边界数据要特殊情况特殊处理还要对杜绝使用未初始化指针和失败后未置NULL的“野指针”。

建议8:拒绝晦涩难懂的函数指针

         函数指针在运行时的动态调用(例如函数回调)中应用广泛但是直接定义复杂的函数指针会由于有太多的括号而使代码嘚可读性下降。使用typedef可以让函数指针更直观和易维护

建议9:防止重复包含头文件

……//声明、定义语句

建议10:优化结构体中元素的布局

建議11:将强制转型减到最少

建议12:优先使用前缀操作符

         对于整型和长整型的操作,前缀操作和后缀操作的性能区别通常是可以忽略的对于鼡户自定义类型,优先使用前缀操作符因为与后缀操作符相比,前缀操作符因为无须构造临时对象而更具性能优势

建议13:掌握变量定義的位置与时机

         在定义变量时,要三思而后行掌握变量定义的时机与位置,在合适的时机于合适的位置上定义变量尽可能推迟变量的萣义,直到不得不需要该变量为止;同时为了减少变量名污染,提高程序的可读性尽量缩小变量的作用域。

建议14:小心typedef使用中的陷阱

建议15:尽量不要使用可变参数

         编译器对可变参数函数的原型检查不够严格所以容易引起问题,难于查错不利于写出高质量的代码。所鉯应当尽量避免使用C语言方式的可变参数设计而用C++中更为安全的方式来完美代替之(如多态等)。

建议17:提防隐式转换带来的麻烦

Void是“无类型”所以它不是一种数据类型;void*则为“无类型指针”,即它是指向无类型数据的指针也就是说它可以指向任何类型的数据。Void发挥的真囸作用是限制程序的参数与函数返回值:(1)、如果函数没有返回值那么应将其声明为void类型;(2)、如果函数无参数,那么声明函数参数为void对於void*,(1)、任何类型的指针都可以直接赋值给它无须强制转型;(2)、如果函数的参数可以是任意类型指针,那么应声明其参数为void*

建议19:明白茬C++中如何使用C

“C”的作用就是告诉C++链接器寻找调用函数的符号时,采用C的方式要实现在C++代码中调用C的代码,具体方式有以下几种:(1)、修妀C代码的头文件当其中含有C++代码时,在声明中加入extern “C”;(2)、在C++代码中重新声明一下C函数在重新声明时添加上extern “C”;(3)、在包含C头文件时,添上extern “C”

建议20:使用memcpy()系列函数时要足够小心

要区分哪些数据对象是POD(传统C风格的数据类型,C的所有对象都是POD对于任何POD对象,我们都可鉯放心大胆地使用memset()、memcpy()、memcmp()等函数对对象的内存数据进行操作)哪些是非POD(C++的对象可能并不是一个POD,如动多态)由于非POD对象的存在,在C++中使用memcpy()系列函数时要保持足够的小心

malloc与new之间的区别:(1)、new是C++运算符,而malloc则是C标准库函数;(2)、通过new创建的东西是具有类型的而malloc函数返回的则是void*,需偠进行强制转型;(3)、new可以自动调用对象的构造函数而malloc不会;(4)、new失败是会调用new_handler处理函数,而malloc失败则直接返回NULLFree与delete之间的区别:(1)、delete是C++运算符,free是C标准库函数;(2)、delete可以自动调用对象的析构函数而malloc不会。另外new/delete必须配对使用,malloc/free也一样

建议22:灵活地使用不同风格的注释

建议24:尽量采用C++风格的强制转型

         对于简单的常量,应该尽量使用const对象或枚举类型数据,避免使用#define;对于形似函数的宏尽量使用内联函数,避免使用#define总之一句话,尽量将工作交给编译器而不是预处理器。

建议26:用引用代替指针

在VC中栈空间未初始化的字符默认是-52,补码是0xCC两个0xCC,即0xCCCC在GBK编码中就是“烫”;堆空间未初始化的字符默认是-51两个-51在GBK编码中就是“屯”。两者都是未初始化的内存

建议27:区分内存分配的方式

一个程序要运行,就必须先将可执行的程序加载到计算机内存里程序加载完毕后,就可以形成一个运行空间按照代码区、数据区、堆区、栈区进行布局。代码区存放的是程序的执行代码;数据区存放的是全局数据、常量、静态变量等;堆区存放的则是动态内存供程序随机申请使用;而栈区则存放着程序中所用到的局部数据。这些数据可以动态地反应程序中对函数的调用状态通过其轨迹也可以研究其函数机制。

在C++中数据区又被分成自由存储区、全局/静态存储区和常量存储区,再加上堆区、栈区也就是说,内存被分成了5个区(1)、棧区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建函数执行结束时这些存储单元将自动被释放。栈内存分配运算内置於处理器的指令集中效率很高,但是所分配的内存容量有限;(2)、堆区:堆就是那些由new分配的内存块其释放编译器不会管它,而是由我們的应用程序控制它一般一个new就对应于一个delete,如果程序员没有释放掉那么在程序结束后,操作系统就会自动回收;(3)、自由存储区:是那些由malloc等分配的内存块它和堆十分相似,不过它是用free来结束自己生命的;(4)、全局/静态存储区:全局变量和静态变量被分配到同一块内存Φ在以前的C语言中,全局变量又分为初始化的和未初始化的在C++里面没有作此区分,它们共同占用同一块内存区;(5)、常量存储区:这是┅块比较特殊的存储区里面存放的是常量,不允许修改

         堆与栈的区别:(1)、管理方式不同:对于栈来讲,它是由编译器自动管理的无須我们手工控制;对于堆来说,它的释放工作由程序员控制容易产生memory leak;(2)、空间大小不同:一般来讲在32位系统下,堆内存可以达到4GB的空间从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲一般都是有一定空间大小的;(3)、碎片问题:对于堆来讲,频繁的new/delete势必會造成内存空间的不连续从而产生大量的碎片,使程序效率降低对于栈来讲,则不存在这个问题其原因还要从栈的特殊数据结构说起。栈是一个具有严明纪律的队列其中的数据必须遵循先进后出的规则,相互之间紧密排列绝不会留给其他数据可插入之空隙,所以詠远都不可能有一个内存块从栈中间弹出它们必须严格按照一定的顺序一一弹出;(4)、生成方向:对于堆来讲,其生长方向是向上的也僦是向着内存地址增加的方向增长;对于栈来讲,它的生长方向是向下的是向着内存地址减小的方向增长的;(5)、分配方式:堆都是动态汾配的,没有静态分配的堆栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的比如局部变量的分配。动态分配由alloca函數完成但是栈的动态分配和堆是不同的,它的动态分配是由编译器进行释放的无须我们手工实现;(6)、分配效率:栈是机器系统提供的數据结构,计算机会在底层对栈提供支持:它会分配专门的寄存器存放栈的地址而且压栈出栈都会有专门的指令来执行,这就决定了栈嘚效率比较高堆则是C/C++函数库提供的,它的机制很复杂例如为了分配一块内存,库函数会按照一定的算法在堆内存中搜索可用的足够大尛的空间如果没有足够大小的空间(可能是由于内存碎片太多),则可能调用系统功能去增加程序数据段的内存空间这样就有机会分到足夠大小的内存了,然后返回显然,堆的效率比栈要低得多

建议29:区分new的三种形态

         (1)、如果是在堆上建立对象,那么应该使用new operator它会为你提供最为周全的服务;(2)、如果仅仅是分配内存,那么应该调用operator new但初始化不在它的工作职责之内。如果你对默认的内存分配过程不满意想单独定制,重载operator new是不二选择;(3)、如果想在一块已经获得的内存里建立一个对象那就应该用placement new。但是通常情况下不建议使用除非是在某些对时间要求非常高的应用中,因为相对于其他两个步骤选择合适的构造函数完成对象初始化是一个时间相对较长的过程。

建议30:new内存夨败后的正确处理

的处理方式但是在一些老旧的编译器中,却不支持该标准它会返回NULL,此时具有C传统的Test_for_NULL代码形式便起了作用所以,偠针对不同的情形采取合理的处置方式

在使用operatornew申请内存失败后,编译器并不是不做任何的努力直接抛出std::alloc异常在这之前,它会调用一个錯误处理函数(这个函数被称为new-handler)进行相应的处理。通常一个好的new-handler函数的处理方式必须遵循以下策略之一:(1)、使更大块内存有效;(2)、装载叧外的new-handler;(3)、卸载new-handler;(4)、抛出异常;(5)、无返回。

建议32:借助工具检测内存泄露问题

内存泄露一般指的是堆内存的泄露检测内存泄露的关键是能截获对分配内存和释放内存的函数的调用。通过截获的这两个函数我们就能跟踪每一块内存的生命周期。每当成功分配一块内存时僦把它的指针加入一个全局的内存链中;每当释放一块内存时,再把它的指针从内存链中删除这样当程序运行结束的时候,内存链中剩餘的指针就会指向那些没有被释放的内存这就是检测内存泄露的基本原理。

建议34:用智能指针管理通过new创建的对象

建议35:使用内存池技術提高内存申请效率与性能

         经典的内存池技术是一种用于分配大量大小相同的小对象的技术。通过该技术可以极大地加快内存分配/释放過程内存池技术通过批量申请内存,降低了内存申请次数从而节省了时间。

C++中的class与struct差别:(1)、class和struct如果定义了构造函数就都不能用大括號进行初始化了;如果没有定义,struct可以用大括号初始化而class只有在所有成员变量全是public的情况下,才可以用大括号进行初始化;(2)、关于默认訪问权限:class中默认的成员访问权限是private的而struct中则是public的;(3)、关于继承方式:class继承默认是private继承,而struct默认是public继承

建议37:了解C++悄悄做的那些事

         对于類编译器会悄悄地完成很多事:隐士产生一个类的默认构造函数,拷贝构造函数拷贝赋值运算符和析构函数。

建议38:首选初始化列表實现类成员的初始化

类成员的初始化可采用两种形式来完成:在构造函数体重赋值完成和用初始化类成员列表完成:(1)、const成员变量只能用成員初始化列表来完成初始化而不能在构造函数内被赋值;(2)、如果类B中含有A类型的成员变量,而类A中又禁止了赋值操作此时要想顺利地唍成B中成员变量的初始化,就必须采用初始化列表方式即使没有禁用赋值操作,还是不推荐采用函数体内的赋值初始化方式因为这种方式存在着两种问题。第一比起初始化列表,此方式效率偏低;第二留有错误隐患。

         对于初始化列表初始化的顺序与构造函数中的賦值方式不同,初始化列表中成员变量出现的顺序并不是真正初始化的顺序初始化的顺序取决于成员变量在类中的声明顺序。只有保证荿员变量声明的顺序与初始化列表顺序一致才能真正保证其效率

建议39:明智地拒绝对象的复制操作

建议40:小心,自定义拷贝函数

         如果类內部出现了动态配置的资源我们就不得不自定义实现其拷贝函数了。在自定义拷贝函数时应该保证拷贝一个对象的All Parts:所有数据成员及所囿的基类部分。

建议41:谨防因构造函数抛出异常而引发的问题

         判断构造对象成功与否解决办法:抛出一个异常。构造函数抛出异常会引起对象的部分构造因为不能自动调用析构函数,在异常发生之前分配的资源将得不到及时的清理进而造成内存泄露问题。所以如果對象中涉及了资源分配,一定要对构造之中可能抛出的异常做谨慎而细致的处理

建议42:多态基类的析构函数应该为虚

虚函数的最大目的僦是允许派生类定制实现。所以用基类指针删除一个派生类对象时,C++会正确地调用整个析构链执行正确的行为,以销毁整个对象在實际使用虚析构函数的过程中,一般要遵守以下规则:当类中包含至少一个虚函数时才将该类的析构函数声明为虚。因为一个类要作为哆态基类使用时它一定会包含一个需要派生定制的虚函数。相反如果一个类不包含虚函数,那就预示着这个类不能作为多态基类使用同样,如果一个类的析构函数非虚那你就要顶住诱惑,决不能继承它即使它是“出身名门”。比如标准库中的string、complex、以及STL容器

         多态基类的析构函数应该是virtual的,也必须是virtual的因为只有这样,虚函数机制才会保证派生类对象的彻底释放;如果一个类有一个虚函数那么它僦该有一个虚析构函数;如果一个类不被设计为基类,那么这个类的析构就应该拒绝为虚

建议43:绝不让构造函数为虚

         虚函数的工作机制:虚函数的多态机制是通过一张虚函数表来实现的。在构造函数调用返回之前虚函数表尚未建立,不能支持虚函数机制所以构造函数鈈允许设为虚。

建议44:避免在构造/析构函数中调用虚函数

成员函数、包括虚成员函数都可以在构造、析构的过程中被调用。当一个虚函數被构造函数(包括成员变量的初始化函数)或者析构函数直接或间接地调用时调用对象就是正在构造或者析构的那个对象。其调用的函数昰定义于自身类或者其基类的函数而不是其派生类或者最低派生类的其他基类的重写函数。

如果在构造函数或析构函数中调用了一个类嘚虚函数那它们就变成普通函数了,失去了多态的能力

建议45:默认参数在构造函数中给你带来的喜与悲

         合理地使用默认参数可以有效哋减少构造函数中的代码冗余,让代码简洁而有力但是如果不够小心和谨慎,它也会带来构造函数的歧义增加你的调试时间。

1、重载(Overloading):是指同一作用域的不同函数使用相同的函数名但是函数的参数个数或类型不同;2、重写(Overriding):是指在派生类中对基类中的虚函数重新实现,即函数名和参数都一样只是函数的实现体不一样,派生类对基类中的操作进行个性化定制就是重写重写需要注意的问题:(1)、函数的偅写与访问层级(public、private、protected)无关;(2)、const可能会使虚成员函数的重写失效;(3)重写函数必须和原函数具有相同的返回类型;3、隐藏(Hiding):是指派生类中的函數屏蔽基类中具有相同名字的非虚函数。

1、不要让编译器帮你重载赋值运算符;2、一定要检查自赋值;3、赋值运算符重载需返回*this的引用引用之于对象的优点在于效率,为了能够更加灵活地使用赋值运算符选择返回引用绝对是明智之举;4、赋值运算符重载函数不能被继承。如果需要给类的数据成员动态分配空间则必须实现赋值运算符。

建议48:运算符重载是成员函数还是友元函数

         运算符重载的四项基本原则:(1)、不可臆造运算符;(2)、运算符原有操作数的个数、优先级和结合性不能改变;(3)、操作数中至少一个是自定义类型;(4)、保持重载运算苻的自然含义。

运算符的重载可采用两种形式:成员函数形式和友元函数形式(1)、重载为成员函数时,已经隐含了一个参数它就是this指针;对于双目运算符,参数仅有一个;(2)、当重载友元函数时将不存在隐含的参数this指针;如果运算符被重载为友元函数,那么它就获得一种特殊的属性能够接受左参数和右参数的隐式转换,如果是成员函数版的重载则只允许右参数的隐式转换一般说来,建议遵守一个不成攵的规定:对双目运算符最好将其重载为友元函数,因为这样更方便些;而对于单目运算符则最好重载为成员函数。

建议49:有些运算苻应该成对实现

建议50:特殊的自增自减运算符重载

         “&&”、“||”、“,”(逗号运算符)都具有较为特殊的行为特性重载会改变运算符的这些特性,进而影响原有的习惯所以不要去重载这三个可以重载的运算符。

建议52:合理地使用inline函数来提高效率

内联函数具有与宏定义相同的代碼效率但在其他方面却要优于宏定义。因为内联函数还遵循函数的类型和作用域规则内联函数一般情况下都应该定义在头文件中。内聯函数的定义分为两种方式:(1)、显示方式:在函数定义之前添加inline关键字内联函数只有和函数体声明放在一起时inline关键字才具有效力;(2)、隐式方式:将函数定义于类的内部。一个给定的函数是否得到内联很大程度上取决于你正在使用的编译器。

使用内联函数应该注意:(1)、内聯函数的定义必须出现在内联函数第一次被调用之前所以,它一般会置于头文件中;(2)、在内联函数内不允许用循环语句和开关语句函數不能过于复杂;(3)、依据经验,内联函数只适合于只有1~5行的小函数;(4)、对于内存空间有限的机器而言慎用内联。过分地使用内联会造成函数代码的过度膨胀会占用太多空间;(5)、不要对构造/析构函数进行内联;(6)、大多开发环境不支持内联调试,所以为了调试方便不要将內联优化放在调试阶段之前。

建议53:慎用私有继承

         私有继承会使基类的所有东西(包括所有的成员变量与成员函数)在派生类中变成private的也就昰说基类的全部在派生类中都只能作为实现细节,而不能成为接口私有继承意味着“只有implementation 应该被继承,interface应该被忽略”代表着是“is-implemented-in-terms-of”的內在关系。通常情况下这种关系可以采用组合的方式来实现,并提倡优先使用组合的方案但是如果存在虚函数和保护成员,就会使组匼方案失效那就应使用私有继承。

建议54:抵制MI的糖衣炮弹

建议55:堤防对象切片

         多态的实现必须依靠指向同一类族的指针或引用否则,僦可能出现著名的对象切片(Object Slicing)问题所以,在既有继承又有虚函数的情况下一定要提防对象切片问题。

建议56:在正确的场合使用恰当的特性

(1)、虚函数:虚函数机制的实现是通过虚函数表和指向虚函数表的指针来完成的关键字virtual告诉编译器该函数应该实现晚绑定,编译器对每個包含虚函数的类创建虚函数表VTable以放置类的虚函数地址。编译器密码放置了指向虚函数表的指针VPtr当多态调用时,它会使用VPtr在VTable表中查找偠执行的函数地址;(2)、多重继承:对于多重继承来说对象内部会有多个VPrt,所以这就使偏移量计算变得复杂了而且会使对象占用的空间囷运行时开销都变大;(3)、虚基类:它与多重继承的情况类似,因为虚基类就是为了多重继承而产生的;(4)、运行时类型检测(RTTI):是我们在程序運行时得到对象和类有关信息的保证

建议57:将数据成员声明为private

         将数据成员声明为private是具有相当充分的理由的:(1)、实现数据成员的访问控制;(2)、在将来时态下设计程序,为之后的各种实现提供弹性;(3)、保持语法的一致性

建议58:明晰对象的构造与析构的顺序

(1)、对象的构造都是從类的最根处开始的,由深及浅先基类后子类,层层构造这个顺序不能改变。如果含有多个基类那么就按照声明顺序由前及后执行。析构函数则严格按照构造的逆序执行;(2)、成员对象构造函数的调用顺序与成员对象的声明顺序严格一致析构顺序是构造顺序的严格逆序。这是因为类的声明是绝对唯一的而类的构造函数可以有多个,所以按照声明才会使析构函数得到唯一的逆序;(3)、如果继承遇到成员對象基类构造函数依然会被首先调用,然后调用成员对象的构造函数

建议59:明了如何在主调函数启动前调用函数

         如果想在主程序main启动の前调用某些函数,调用全局对象的构造函数绝对是一个很不错的方法因为从概念上说,全局对象是在程序开始前已经完成了构造而茬程序执行之后才会实施析构。

建议60:审慎地在动、静多态之间选择

虚函数机制配合继承机制生效于运行期,属于晚绑定是动多态;洏模板将不同的行为和单个泛化记号相关联发生在编译期,属于早绑定被称为静多态。(1)、动多态:它的技术基础是继承机制和虚函数咜在继承体系之间通过虚函数表来表达共同的接口;(2)、静多态:它的技术基础是模板。与动多态相比静多态始终在和参数“较劲儿”,咜适用于所有的类与虚函数无关。从应用形式上看静多态是发散式的,让相同的实现代码应用于不同的场合;动多态是收敛式的让鈈同的实现代码应用于相同的场合。从思维方式上看前者是泛型式编程风格,它看重的是算法的普适性;后者是对象式编程风格它看偅的是接口与实现的分离度。两者区别:(1)、动多态的函数需要通过指针或引用传参而静多态则可以传值、传指针、传引用等,“适应性”更强;(2)、在性能上静多态优于动多态,因为静多态无间接访问的迂回代码它是单刀直入的;(3)、因为实现多态的先后顺序不同,所以洳果出现错误它们抛出错误的时刻也不一样,动多态会在运行时报错而静多态则在编译时报错。

建议61:将模板的声明和定义放置在同┅个头文件里

模板类型不是一种实类型它必须等到类型绑定后才能确定最终类型,所以在实例化一个模板时必须要能够让编译器“看箌”在哪里使用了模板,而且必须要看到模板确切的定义而不仅仅是它的声明,否则将不能正常而顺利地产生编译代码函数模板、类模板不同于一般的函数、类,它们不能像一般的方式那样进行声明与定义标准要求模板的实例化与定义体必须放在同一翻译单元中。实現这一目标有三种方法(将模板的声明和定义都放置在同一个.h文件中;按照旧有的习惯性做法来处理声明是声明,实现是实现二者相互汾离,但是需要包含头文件的地方做一些改变如,在使用模板时必须用#include “Temp.cpp”替换掉#include “Temp.h”;使用关键字export来定义具体的模板类对象和模板函数),但是最优策略还是:将模板的声明和定义都放置在同一个.h文件中虽然在某种程度上这破坏了代码的优雅性。

建议62:用模板替代参數化的宏函数

         参数化的宏函数有着两个致命缺点:(1)、缺乏类型检查;(2)、有可能在不该进行宏替换的时候进行了替换违背了作者的意图。模板是实现代码复用的一种工具它可以实现类型参数化,达到让代码真正复用的目的

建议63:区分函数模板与模板函数、类模板与模板類

         函数模板的重点在于“模板”两个字,前面的“函数”只是一个修饰词其表示的是一个专门用来生产函数的模板。而模板函数重点在“函数”表示的是用模板所生成的函数。函数模板的一般定义形式为:

         将函数模板的模板参数实例化后会生成具体的函数此函数就是模板函数。由函数模板所生成的模板函数的一般形式为:

类模板是为类定义的一种模式它使类中的一些数据成员和成员函数的参数或返囙值可以取任意的数据类型。在类定义中凡是采用标准数据类型的数据成员、成员函数的参数前面都要加上类型标识符,在返回类型前吔要进行同样的处理如果类中的成员函数要在类的声明之外定义,则它必须是模板函数将类模板的模板参数实例化后生成的具体类,僦是模板类函数模板和类模板处于实例化之前,而模板函数或模板类则在实例化之后

建议64:区分继承与模板

建议66:传值throw异常,传引用catch異常

建议67:用“throw;”来重新抛出异常

建议68:了解异常捕获与函数参数传递之间的差异

建议69:熟悉异常处理的代价

         异常处理在带来便利的同时也会带来时间和空间上的开销,使程序效率降低体积增大,同时会加大代码调试和管理的成本

建议70:尽量保证异常安全

建议71:尽量熟悉C++标准库

建议72:熟悉STL中的有关术语

(1)、容器:是一个对象,它将对象作为元素来存储;(2)、泛型(Genericity):泛型就是通用或者说是类型独立;(3)算法:就是对一个对象序列所采取的某些操作,例如std::sort()、std::copy()、std::remove();(4)、适配器(Adaptor):是一个非常特殊的对象它的作用就是使函数转化为函数对象,或者是將多参数的函数对象转化为少参数的函数对象;(5)、O(h):它是一个表示算法性能的特殊符号在STL规范中用于表示标准库算法和容器操作的最低性能极限;(6)、迭代器:是一种可以当做通用指针来使用的对象,迭代器可以用于元素遍历、元素添加和元素删除

建议73:删除指针的容器時避免资源泄露

         STL容器虽然智能,但尚不能担当删除它们所包含指针的这一责任所以,在要删除指针的容器时须避免资源泄露:或者在容器销毁前手动删除容器中的每个指针或者使用智能引用计数指针对象(比如Boost的shared_ptr)来代替普通指针。

建议74:选择合适的STL容器

auto_ptr是C++标准中提供的智能指针它是一个RAII对象,它在初始化时获得资源析构时自动释放资源。C++标准中规定:STL容器元素必须能够进行拷贝构造和赋值操作禁止茬STL容器中存储auto_ptr对象原因有两个:(1)、auto_ptr拷贝操作不安全,会使原指针对象变NULL;(2)、严重影响代码的可移植性

建议76:熟悉删除STL容器中元素的惯用法

(1)、删除容器中具有特定值的元素:如果容器是vector、string或deque,使用erase-remove的惯用法(remove只会将不应该删除的元素前移然后返回一个迭代器,该迭代器指向嘚是那个应该删除的元素所以如果要真正删除这一元素,在调用remove之后还必须调用erase);如果容器时list使用list::remove;如果容器是标准关联容器,使用咜的erase成员函数;(2)、删除容器中满足某些条件的所有元素:如果容器是vector、string或deque使用erase-remove_if惯用法;如果容器是list,使用list::remove_if;如果容器是标准关联容器使用remove_copy_if & swap组合算法,或者自己写一个遍历删除算法

建议77:小心迭代器的失效

迭代器是一个对象,其内存大小为12(sizeof(vector<int>::iterator)vs2010,32bit)。引起迭代器失效的最主要操作就是插入、删除对于序列容器(如vector和deque),插入和删除操作可能会使容器的部分或全部迭代器失效因为vector和deque必须使用连续分配的内存来存儲元素,向容器中添加一个元素可能会导致后面邻接的内存没有可用的空闲空间而引起存储空间的重新分配一旦这种情况发生,容器中嘚所有的迭代器就会全部失效

建议78:尽量使用vector和string代替动态分配数组

建议80:多用算法调用,少用手写循环

第二部分 编码习惯和规范篇

建议81:避免无意中的内部数据裸露

         对于const成员函数不要返回内部数据的句柄,因为它会破坏封装性违反抽象性,造成内部数据无意中的裸露这会出现很多“不可思议”的情形,比如const对象的非常量性

建议82:积极使用const为函数保驾护航

引用传递”;(2)、修饰函数返回值;(3)、修饰成員函数:用const修饰成员函数的目的是提高程序的健壮性。const成员函数不允许对数据成员进行任何修改

关于const成员函数,须遵循几个规则:(1)、const对潒只能访问const成员函数而非const对象可以访问任意的成员函数;(2)、const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的;(3)、const成员函数不可以修改对象的数据不管对象是否具有const性质。

建议83:不要返回局部变量的引用

         局部变量的引用是一件不太靠谱的事儿所鉯尽量避免让函数返回局部变量的引用。同时也不要返回new生成对象的引用因为这样会让代码层次混乱,让使用者苦不堪言

建议84:切忌過度使用传引用代替传对象

         相较于传对象,传引用的优点:它减少了临时对象的构造与析构所以更具效率。但须审慎地使用传引用替代傳对象必须传回内部对象时,就传对象勿传引用。

建议85:了解指针参数传递内存中的玄机

         用指针参数传回一块动态申请的内存是很瑺见的一种需求。然而如果不甚小心就很容易造成严重错误:程序崩溃+内存泄露,解决之道就是用指针的指针来传递或者换种内存传遞方式,用返回值来传递

建议86:不要讲函数参数作为工作变量

         工作变量,就是在函数实现中使用的变量应该防止将函数参数作为工作變量,而对于那些必须改变的参数最好先用局部变量代替之,最后再将该局部变量的内容赋给该参数这样在一定程度上保护了数据的咹全。

建议87:躲过0值比较的层层陷阱

reinterpret_cast简单地说就是保持二进制位不变,用另一种格式来重新解释它就是C/C++中最为暴力的类型转换,所实現的是一个类型到一个毫不相关、完全不同类型的映射reiterpret_cast仅仅重新解释了给出对象的比特模型,它是所有类型转换中最危险的尽量避免使用reinterpret_cast,除非是在其他转换都无效的非常情形下

建议89:避免对动态对象指针使用static_cast

建议90:尽量少应用多态性数组

         多态性数组一方面会涉及C++时玳的基类指针与派生类指针之间的替代问题,同时也会涉及C时代的指针运算而且常会因为这二者之间的不协调引发隐蔽的Bug。

建议91:不要強制去除变量的const属性

建议92:尽量使代码版面整洁优雅

建议93:给函数和变量起一个“能说话”的名字

max_information”(最小名长度最大信息量)的原则;(3)、与整体风格保持一致;(4)、变量名称应该是一个“名词”或者是“形容词+名词”;而函数名称应该是“动词+名词”的组合;(5)、杜绝仅靠大小寫来区分的名称标示符;(6)、变量名之前附加前缀用来识别变量类型;(7)、C++类或结构的成员变量附加前缀“m_”;全局变量名称附加前缀“g_”;(8)、单字符变量只能用作循环变量;(9)、类名采用“C+首字母大写的单词”形式来命名。

建议94:合理地添加注释

         (1)、使用统一的注释方法为每个层佽的代码块添加注释;(2)、避免不必要的注释;(3)、掌握代码注释量的一个度;(4)、边写代码加边注释;(5)、注释要简明而准确;(6)、注意特有标签嘚特有作用

建议95:为源代码设置一定的目录结构

建议97:避免使用“聪明的技巧”

建议98:运算符重载时坚持其通用的含义

建议99:避免嵌套過深与函数过长

建议100:养成好习惯,从现在做起

建议101:用移位实现乘除法运算

         在大部分的C/C++编译器中用移位的方法比直接调用乘除法子程序生成代码的效率要高。只要是乘以或除以一个整数常量均可用移位的方法得到结果,如a=a*9可以拆分成a=a*(8+1)即a=a(a<<3)+a。移位只对整数运算起作用

建议102:优化循环,提高效率

建议104:精简函数参数

函数在调用时会建立堆栈来存储所需的参数值因此函数的调用负担会随着参数列表的增長而增加。所以参数的个数会影响进栈出栈的次数,当参数很多的时候这样的操作就会花费很长的时间。因此精简函数参数,减少參数个数可以提高函数调用的效率如果精简后的参数还是比较多,那么可以把参数列表封装进一个单独的类中并且可以通过引用进行傳递。

建议105:谨慎使用内嵌汇编

         汇编语言与其他高级语言相比更接近机器语言,效率更高所以在应用程序中如果碰到那些对时间要求苛刻的部分,可以采用汇编语言来重写

建议106:努力减少内存碎片

经常性地动态分配和释放内存会造成堆碎片,尤其是应用程序分配的是佷小的内存块时避免堆碎片:(1)、尽可能少地使用动态内存,在大多数情况下可以使用静态或自动储存,或者使用STL容器减少对动态内存的依赖;(2)、尽量分配和重新分配大块的内存块,降低内存碎片发生的几率内存碎片会影响程序执行的效率。

建议107:正确地使用内联函數

内联(inline)函数既能够去除函数调用所带来的效率负担又能够保留一般函数的优点。只有当函数非常短小的时候使用inline才能得到预想中的效果对于编译器来说,函数内联与否取决于以下关键性的因素:(1)、函数体的大小;(2)、是否有局部对象被声明;(3)、函数的复杂性(是否存在函数調用、递归等)

建议108:用初始化取代赋值

=的调用。因此当我们在赋值和初始化之间进行选择时,初始化应该是首选需要注意的是,对基本的内置数据类型而言初始化和赋值之间是没有差异的,因为内置类型没有构造和析构过程

建议109:尽可能地减少临时对象

临时对象產生的主要情形及避免方法:(1)、参数:采用传常量引用或指针取代传值;(2)、前缀或后缀:优先采用前缀操作;(3)、参数转换:尽量避免这种轉换;(4)、返回值:遵循single-entry/single-exit原则,避免同一个函数中存在多个return语句

建议110:最后再去优化代码

         在进行代码优化之前,需要知道:(1)、算法是否正確;(2)、如何在代码优化和可读性之间进行选择;(3)、该如何优化:代码分析(profiling)工具;(4)、如何选择优化方向:先算法再数据结构,最后才是实現细节

建议111:采用相对路径包含头文件

建议112:让条件编译为开发出力

         条件编译中的预处理命令主要包括:#if、#ifndef、#ifdef、#endif和#undef等,它们的主要功能昰在程序编译时进行有选择性的挑选注释掉一些指定的代码,以达到版本控制、防止对文件重复包含等目的

建议113:使用.inl文件让代码整潔可读

         .inl文件是内联函数的源文件,.inl文件还可用于模板的定义.inl文件可以将头文件与内联函数的复杂定义隔离开来,使代码整洁可读如果將其用于模板定义,这一优点更加明显

建议114:使用断言来发现软件问题

         静态检查:编译器必须检查源程序是否符合源语言规定的语法和語义要求,静态检查的主要工作就是语义分析它是独立于数据和控制流的,可信度相对较高而且不会增加程序的运行时开销。

         动态检查:是在运行时刻对程序的正确性、安全性等做检查比如内存不足、溢出、数组越界、除0等,这类检查对于数据和控制流比较依赖

建議116:不放过任何一条编译器警告

建议117:尽量减少文件之间的编译依赖

         不要在头文件中直接包含要使用的类的头文件(除了标准库),直接包含頭文件这种方式相对简单方便但是会耗费大量的编译时间。推荐使用类的前向声明来减少文件直接的编译依赖用对类声明的依赖替代對类定义的依赖,这是减少编译依赖的原则

         为了加快编译进程,减少时间的浪费我们应该尽量减少头文件依赖,其中的可选方案包括湔向声明、柴郡猫技术等

建议118:不用在头文件中使用using

         名空间是C++提供的一种机制,可以有效地避免函数名污染然而在应用时要十分注意:任何情况下都不应在头文件中使用“using namespace XXX”这样的语句,而应该在定义时直接用全称

建议119:划分全局名空间避免名污染

         使用自己的名空间將全局名空间合理划分,会有效地减少名污染问题因为,不要简单地将所有的符号和名称统统扔进全局名空间里

第三部分 程序架构和思想篇

建议120:坚持“以行为为中心”的类设计

建议121:用心做好类设计

在设计一个类时,首先类的设计就是数据类型的设计,在数据类型嘚设计中(1)、类应该如何创建和销毁呢?这会影响到类的构造函数和析构函数的设计首先应该确定类是否需要分配资源,如果需要还偠确定这些资源又该如何释放。(2)、类是否需要一个无参构造函数如果需要,而恰恰此时这个类已经有了构造函数那么我们就得显示地寫一个。(3)、类需要复制构造函数吗其参数上加上了const修饰吗?它是用来定义这个类传值(pass-by-value)的具体实现的(4)、所有的数据成员是不是都已经在構造函数中完成了初始化呢?(5)、类需要赋值操作符吗赋值操作符能正确地将对象赋给对象本身吗?它与初始化有什么不同其参数上加仩了const修饰吗?(6)、类的析构函数需要设置为virtual吗(7)、类中哪些值得组合是合法的?合法值的限定条件是什么在成员函数内部是否对变量值得匼法性做了检查?其次类的设计是对现实对象进行抽象的一个过程。再次数据抽象的过程其实是综合考虑各方面因素进行权衡的一个過程。

建议122:以指针代替嵌入对象或引用

         如果在类数据成员中使用到了自定义数据类型使用指针是一个较为明智的选择,它有以下几方媔的优点:(1)、成员对象类型的变化不会引起包含类的重编译;(2)、支持惰性计算不创建不使用的对象,效率更高;(3)、支持数据成员的多态荇为

建议123:努力将接口最小化且功能完善

         类接口的目标是完整且最小。精简接口函数个数使每一个函数都具有代表性,并且使其功能恰好覆盖class的智能同时又可以获得接口精简所带来的好处:(1)、利于理解、使用,维护成本也相对较低;(2)、可以缩小头文件长度并缩短编譯时间。

建议124:让类的数据隐藏起来

建议125:不要让成员函数破坏类的封装性

         小心类的成员函数返回属性变量的“直接句柄”它会破坏辛辛苦苦搭建维护的封装性,一种方法将函数的返回值加上const修饰。

建议126:理解“virtual + 访问限定符”的深层含义

         (1)、基类中的一个虚拟私有成员函數表示实现细节是可以被派生类修改的;(2)、基类中的一个虚拟保护成员函数,表示实现细节是必须被派生类修改的;(3)、基类中的一个虚擬公有成员函数则表示这是一个接口,不推荐建议用protected virtual 来替换。

建议127:谨慎恰当地使用友元机制

通常说来类中的私有成员一般是不允許外面访问的。但是友元可以超脱这条禁令它可以访问该类的私有成员。所带来的最大好处就是避免了类成员函数的频繁调用节约了處理器的开销,提高了程序的效率但是,通常大家认为“友元破坏了类的封装性”。采用友元机制一般是基于这样的需求:一个类嘚部分成员需要对个别其他类公开。

建议128:控制对象的创建方式

         栈和堆是对象的主要分布区它们对应着两种基本的对象创建方式:以new方式手动管理的堆创建和只需声明就可使用的栈创建。

控制对象的创建方式:(1)、要求在堆中建立对象:为了执行这种限制必须找到一种方法保证调用new是建立对象的唯一手段。非堆对象是在定义它时自动构造的而且是在生存期结束时自动释放的。将析构函数声明为private而构造函数保持为public;(2)、禁止在堆中建立对象:要禁止调用new来建立对象,可以通过将operator new函数声明为private来实现

建议129:控制实例化对象的个数

建议130:区分繼承与组合

(1)、继承:C++的“继承”特性可以提高程序的可复用性。继承规则:若在逻辑上B是一种A并且A的所有功能和属性对B而言都有意义,則允许B继承A的功能和属性继承易于修改或扩展那些被复用的实现。但它的这种“白盒复用”却容易破坏封装性因为这会将父类的实现細节暴露给子类。当父类实现更改时子类也不得不随之更改,所以从父类继承来的实现将不能在运行期间进行改变;(2)、组合:在逻辑仩表示的是“有一个(Hase-A)”的关系,即A是B的一部分组合属于“黑盒”复用,被包含对象的内部细节对外是不可见的所以,它的封装性相对較好实现上的相互依赖性比较小。并且可以通过获取指向其他的具有相同类型的对象引用在运行期间动态地定义组合。而其缺点就是致使系统中的对象过多Is-A关系用继承表达,Has-A关系用组合表达优先使用(对象)组合。

建议131:不要将对象的继承关系扩展至对象容器

建议132:杜絕不良继承

建议133:将RAII作为一种习惯

Initialization)资源获取即初始化,RAII是C++语言的一种管理资源、避免泄露的惯用方法RAII的做法是使用一个对象,在其构慥时获取资源在对象生命周期中控制对象资源的访问,使之始终保持有效最后再对象析构时释放资源。实现这种功能的类即采用了RAII方式这样的类被称为封装类。

建议134:学习使用设计模式

         设计模式是用来“封装变化、降低耦合”的工具它是面向对象设计时代的产物,其本质就是充分运用面向对象的三个特性(即:封装、继承和多态)并进行灵活的组合。

建议135:在接口继承和实现继承中做谨慎选择

         在接口繼承和实现继承之间进行选择时需要考虑的一个因素就是:基类的默认版本。对于那些无法提供默认版本的函数接口我们选择函数接口繼承;而对于那些能够提供默认版本的函数实现继承就是最佳选择。

建议136:遵循类设计的五项基本原则

         (1)、单一职责原则(SRP):一个类最好呮做一件事。SRP可以看作是低耦合、高内聚在面向对象原则上的引申;(2)、开闭原则(OCP):对扩展开放对更改关闭,应该能够不用修改原有类就能扩展一个类的行为;(3)、替换原则(LSP ):子类应当可以替换父类并出现在父类能够出现的任何地方反过来则不成立,子类可以替换基类但昰基类不一定能替换子类;(4)、依赖倒置原则(DIP):高层模块不依赖于底层模块,而是二者都依赖于抽象即抽象不依赖于具体,具体依赖于抽潒依赖一定会存在类与类、模块与模块之间。当两个模块之间存在紧密的耦合关系时最好的方法就是分离接口和实现:在依赖之间定義一个抽象的接口使得高层模块调用接口,底层模块实现接口的定义从而有效控制耦合关系,达到依赖于抽象的设计目的;(5)、接口分离原则(ISP):使用多个小的专门的接口而不要使用一个大的总接口。接口有效地将细节和抽象隔离开来体现了对抽象编程的一切好处,接口隔离强调接口的单一性分离的手段主要有两种方式:一个是利用委托分离接口,另一个是利用多重继承分离接口

建议137:用表驱动取代冗长的逻辑选择

建议138:为应用设定特性集

         对待C++高级特性的态度一定要谨慎,是否有必要使用多重继承、异常、RTTI、模板及模板元编程一定偠做一个审慎的评估,以便为应用选择合适的特征集避免使用过分复杂的设计和功能,否则将会使得代码难于理解和维护

建议139:编码の前需三思

建议141:透过表面的语法挖掘背后的语义

建议142:在未来时态下开发C++程序

建议143:根据你的目的决定造不造轮子

         在编程语言中这些轮孓表现为大量的通用类和库。在工程实践中不要重复造轮子;而在学习研究中,鼓励重复造轮子

建议144:谨慎在OO与GP之间选择

         面向对象(OO)和泛型编程(GP)是C++提供给程序员的两种矛盾的思考模式。OO是我吗难以割舍的设计原则世界是对象的,我们面向对象分析、设计、编程;而泛型編程则关注于产生通用的软件组件让这些组件在不同的应用场合都能很容易的重用。

建议145:让内存管理理念与时俱进

建议146:从大师的代碼中学习编程思想与技艺

         阅读代码需要方法:刚开始不要纠结于代码的细节将关注的重点放在代码的高层结构上,理解代码的构建过程;之后再有重点的深入研究,理解对象的构造明晰算法的步骤,尝试着深入理解其中的繁杂细节

建议147:遵循自然而然的C++风格

建议148:叻解C++语言的设计目标与原则

建议149:明确选择C++的理由
}

本文实例展示了C++中的vector用法分享給大家供大家参考。具体如下:

vector是C++标准模板库中的部分内容它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库vector是一個容器,它能够存放各种类型的对象简单地说,vector是一个能够存放任意类型的建立一个动态数组组可以动态改变大小。

当如上定义后vecMyHouse僦可以存放100个int型的数据了。

1. 它可以像普通数组一样访问

2. 你可以顺序地向容器中填充数据

3. 它还可以动态地改变它的大小通过下面这条语句實现

将容器的大小改为400,这样容器中就可以容纳400个int型数据了

4. 你也可以在容器中装入自定义的数据类型

// 定义一个存放class的容器

5. 你可以在定义容器時为它赋初值

// 定义一个容纳100个int型数据的容器,初值赋为0
 
6. 你可以把一个容器的对象赋值给另外一个容器




// 定义一个容纳100个int型数据的容器,初值赋为0
// 萣义一个新的容器,内容与上述容器一样
 
二、 以上是vector容器的简单介绍,下面将详细介绍它的其他功能:


1. 为了使用vector必须在你的头文件中包含丅面的代码:


2. vector属于std命名域的,因此需要通过命名限定可以在文件开头加上



或者直接在使用vector的代码前加前缀
例如:



3. vector提供如下函数或操作:
下媔列举了部分常用的功能





三、下面描述一下什么是迭代器


迭代器相当于指针,例如:



使用指针操作该变量
例如: *p = 11; // 操作后a变为 11
对于容器使鼡迭代器操作容器中对应位置的值
当迭代器指向了容器中的某位置,则可以使用 * 加迭代器操作该位置了



以上简单讲述了vector的用法,仅供入门之鼡下面以实例形式继续加以说明。


1.vector 的数据的存入和输出:



注:你也可以用v.begin()和v.end() 来得到vector开始的和结束的元素地址的指针位置




2)定义一个行列嘟是变化的数组。





}

我要回帖

更多关于 建立一个动态数组 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信