c++面试高频问题

c++基础,面试高频问题

1. 重载、隐藏、重写(覆盖)三者的区别?

  • 重载:是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型(统一为void,否则报错)。
    运算符重载:使用户自定义的数据以更简洁的方式工作
  • 隐藏(重定义):是指派生类的函数屏蔽了与其同名的基类函数,注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏。
  • 重写(覆盖):是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。

重载的参数不同,函数体不同(同一个类中,同一作用域);
隐藏的参数可以不同,函数体不同;
重写或者覆盖仅仅函数体不同(花括号内)不同的范围(分别位于派生类与基类)。

  • 重载为什么改变参数就可以实现调用不同的函数?
    因为C++在编译的时候会对函数进行重命名,保证函数名的唯一性,而重载函数的参数不同,就会被命名为不同的函数名。
  • 构造函数可以被重载么?析构函数呢?
    构造函数可以被重载,因为构造函数可以有多个且可以带参数。
    析构函数不可以被重载,因为析构函数只能有一个,且不能带参数。
    构造函数主要用来在创建对象时完成对对象属性的一些初始化等操作, 当创建对象时, 对象会自动调用它的构造函数。一般来说, 构造函数有以下三个方面的作用:
    1、给创建的对象建立一个标识符;
    2、为对象数据成员开辟内存空间;
    3、完成对象数据成员的初始化。

2. new/delete和malloc/free的区别?

相同点:都可以用与于内存的动态申请和释放
不同点:

  • new操作符从自由存储区上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。
  • new/delete是C++运算符,malloc/free是标准库函数
  • new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
  • new内存分配失败时,会抛出bac_alloc异常,它不会返回NULL;malloc分配内存失败时返回NULL。
  • 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算,而malloc则需要显式地指出所需内存的尺寸。
  • new/delete会调用对象的构造函数/析构函数以完成对象的构造/析构。而malloc则不会。

3.什么是多态机制?

面向对象的三大特征:封装、继承和多态。

  • 多态就是说同一个名字的函数可以有多种不同的功能。分为编译时的多态和运行时的多态。编译时的多态就是函数重载,包括运算符重载,编译时根据实参确定调用哪个函数。运行时的多态则和虚函数、继承有关。
  • 那多态底层实现是怎么样的?
    利用虚函数表,先构建一个基类,然后在基类的构造函数中会建立虚函数表,也就是一个储存虚函数地址的数组,内存地址的前四个字节保存指向虚函数表的指针,然后当多个子类继承父类之后,主函数中可以通过父类指针调用子类的继承函数。
    虚函数表属于类,也属于它的子类等各种派生类。虚函数表由编译器在编译时生成,保存在.rdata只读数据段。
  • 那子类的多态函数是怎么被调用的?
    因为每个子类都继承并设置了自己的虚函数表,每次用用父类指针创建新子类时就会出现,从而最终调用自己的表。
  • 怎么知道多态时,指向哪个虚函数?
    定义的父类指针new出哪个子类就是指向哪个子类的虚函数。
  • 父类构造函数中是否可以调用虚函数?
    可以。不过调用会屏蔽多态机制,最终会把基类中的该虚函数作为普通函数调用,而不会调用派生类中的被重写的函数。
    这是因为在定义子类对象的时候,会先调用父类的构造函数,而此时虚函数表以及子类函数还没有被初始化,为了避免调用到未初始化的内存,C++标准规范中规定了在这种情况下,即在构造子类时调用父类的构造函数,而父类的构造函数中又调用了虚成员函数,这个虚成员函数即使被子类重写,也不允许发生多态的行为。所以使用的是静态绑定,调用了父类的函数。
  • 静态函数可以是虚函数么?为什么?
    static成员不属于任何类对象或类实例,所以即使给此函数加上virutal也是没有任何意义的。
    静态与非静态成员函数之间有一个主要的区别。那就是静态成员函数没有this指针。所以无法访问vptr. 进而不能访问虚函数表。
  • 虚函数的安全性有什么问题?
    可以通过虚函数表,让父类指针访问子类的自有虚函数。这带来一定的安全问题。另外,即使父类的虚函数是私有函数或者保护函数,仍然可以通过虚函数表访问,带来一定的安全问题。

4.指针和引用的区别

  • 指针指向对象实体存储空间的首地址,且指针本身也是一个实体并占内存空间,引用是给原实体对象内存空间起的别名,引用本身不占内存;
  • 引用在创建时必须初始化,指针可以在任何时候初始化;
  • 引用不可引向NULL,必须确保其引向确定的内存空间,指针可以指向NULL;
  • 引用初始化后不允重新被其他对象引用,指针则可以随意指向其他对象;
  • sizeof(引用)返回的是被引用对象的内存大小,sizeof(指针)返回的是指针本身的大小;
  • 指针和引用作为函数参数时也不同,指针参数可以在函数中改变其指向实体的值,引用传参的本质是传递的实体本身(而不是实体的拷贝),所以在函数中对引用的修改就是对其本身的修改。
  • 指针可以有多级,引用只能有一级

5. C++11新特性!

  • nullptr 出现的目的是为了替代 NULL。在某种意义上来说,传统 C++ 会把 NULL、0 视为同一种东西,这取决于编译器如何定义 NULL,有些编译器会将 NULL 定义为 ((void)0),有些则会直接将其定义为 0。C++ 不允许直接将 void * 隐式转换到其他类型,但如果 NULL 被定义为 ((void*)0),那么当编译char *ch = NULL;时,NULL 只好被定义为 0。为了解决这个问题,C++11 引入了 nullptr 关键字,专门用来区分空指针、0。
  • C++11 引入了 auto 和 decltype 这两个关键字实现了类型推导。decltype 关键字是为了解决 auto 关键字只能对变量进行类型推导的缺陷而出现的
  • 基于范围的 for 循环
for(auto &i : arr) {    
    std::cout << i << std::endl;
}
  • 智能指针Share_ptr, unique_ptr, weak_ptr。
  • Lambda 表达式,实际上就是提供了一个类似匿名函数的特性,而匿名函数则是在需要一个函数,但是又不想费力去命名一个函数的情况下去使用的。Lambda 表达式的基本语法如下:
[ caputrue ] ( params ) opt -> ret { body; };

[]代表传递方式,值传递还是引用传递等。
()括号里是传递的参数
->指明函数返回类型。
{}函数体。

6. 智能指针

  • 动态内存管理经常会出现两种问题:一种是忘记释放内存,会造成内存泄漏;一种是尚有指针引用内存的情况下就释放了它,就会产生引用非法内存的指针。为了更加容易(更加安全)的使用动态内存,引入了智能指针的概念。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。标准库提供的两种智能指针的区别在于管理底层指针的方法不同,shared_ptr允许多个指针指向同一个对象,unique_ptr则“独占”所指向的对象。标准库还定义了一种名为weak_ptr的伴随类,它是一种弱引用,指向shared_ptr所管理的对象,这三种智能指针都定义在memory头文件中。
  • std::unique_ptr 对其持有的堆内存具有唯一拥有权,也就是 std::unique_ptr 不可以拷贝或赋值给其他对象,其拥有的堆内存仅自己独占,std::unique_ptr 对象销毁时会释放其持有的堆内存。
  • std::unique_ptr 对其持有的资源具有独占性,而 std::shared_ptr 持有的资源可以在多个std::shared_ptr 之间共享,每多一个 std::shared_ptr 对资源的引用,资源引用计数将增加 1,每一个指向该资源的std::shared_ptr 对象析构时,资源引用计数减 1,最后一个 std::shared_ptr 对象析构时,发现资源计数为 0,将释放其持有的资源。多个线程之间,递增和减少资源的引用计数是安全的。
  • std::weak_ptr 是一个不控制资源生命周期的智能指针,是对对象的一种弱引用,只是提供了对其管理的资源的一个访问手段,引入它的目的为协助 std::shared_ptr 工作。

当两个对象相互使用一个shared_ptr成员变量指向对方,会造成循环引用,使引用计数失效,从而导致内存泄漏。

7.C++中三种权限的区别

  • Public:可以被任意成员函数访问。
  • Protect:可以被本类或者子类成员函数访问。
  • Private:只能被本类成员函数访问。

8. const关键字

const关键字, 常量指针和指针常量,顶层const和底层const分别是什么?

  • const的作用:被它修饰的值不能改变,是只读变量。必须在定义的时候就给它赋初值。

  • 常量指针(底层const):
    形式:const 数据类型 *指针变量=变量名 或者 数据类型 const 指针变量=变量名
    比如: int temp=10; const int
    a=&temp;或者int const *a=&temp;
    特点:指针指向的值被指针限定住,不能通过指针改变指向的值了

  • 指针常量(顶层const):
    形式: 数据类型 * const 指针变量=变量名
    比如:int temp=10, temp1=12; int* const p=&temp;
    特点:指针的指向的地址不能改变。并且声明时必须初始化。

  • 常指针常量:
    形式:const 数据类型 * const 指针变量=变量名; 或者 数据类型 const const 指针变量=变量名;
    比如:int temp=10; const int
    const p=&temp;
    特点:上述两者的综合,既不能通过指针改变指向的值,指针的指向的地址也不能改变。

  • 区分顶层const和底层const的原因?
    1.底层const的指针不能赋给非底层const。
    2.强制类型转换函数const_cast只能将底层const指针改变为普通指针,其余指针不行。

9. 深拷贝和浅拷贝

  • 浅拷贝只复制某个对象的引用,而不复制对象本身,新旧对象还是共享同一块内存
  • 深拷贝会创造一个一摸一样的对象,新对象和原对象不共享内存,修改新对象不会改变原对对象。
  • 在对含有指针成员的对象进行拷贝时,必须要自己定义拷贝构造函数,使拷贝后的对象指针成员有自己的内存空间,即进行深拷贝,这样就避免了内存泄漏发生。
  • 浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
  • 浅拷贝带来问题的本质在于析构函数释放多次堆内存,使用std::shared_ptr,可以完美解决这个问题

10. C和C++的区别?

  • C语言面向过程,不易扩展;C++面向对象,易扩展。当然C语言也可以通过结构体加函数指针实现面向对象,但是设计复杂。
  • 关键字不同,C99有32个关键字;C++98有63个关键字。struct、class、malloc 、new等关键字有些微小的区别。
  • 返回值不同C语言中,如果一个函数没有指定返回值类型,默认返回int类型;C++中,如果一个函数没有返回值则必须指定为void。
  • 参数列表,在C语言中,函数没有指定参数列表时,默认可以接收任意多个参数;但在C++中,因为严格的参数类型检测,没有参数列表的函数,默认为 void,不接收任何参数。C++缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的参。而C语言不支持缺省参数。
  • 函数重载和引用,C++可以进行函数重载和引用,而C不可以。

11.堆和栈的区别

一个由C/C++编译的程序占用的内存分为以下几个部分

  • 栈区(stack) 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 操作方式类似于数据结构中的栈。

  • 堆区(heap) 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回 收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

  • 全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的 全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另 一块区域。 程序结束后由系统释放。

  • 文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放

  • 程序代码区—存放函数体的二进制代码。

12.Struct和class的区别

  • C++ 中保留了C语言的 struct 关键字,并且加以扩充。在C语言中,struct 只能包含成员变量,不能包含成员函数。而在C++中,struct 类似于 class,既可以包含成员变量,又可以包含成员函数。
  • C++中的 struct 和 class 基本是通用的,唯有几个细节不同:使用 class 时,类中的成员默认都是 private 属性的;而使用 struct 时,结构体中的成员默认都是 public 属性的。
  • class 继承默认是 private 继承,而 struct 继承默认是 public 继承。
  • class 可以使用模板,而 struct 不能。

13.define 和const的区别:

  • 就起作用的阶段而言:define是在编译的预处理阶段起作用,而const是在 编译、运行的时候起作用。
  • 就定义常量说的话:const 定义的常数是变量也带类型, #define 定义的只是个常数不类型。
  • 就起作用的方式而言:define只是简单的字符串替换,没有类型检查。而const有对应的数据类型,是要进行判断的,可以避免一些低级的错误。
  • 从代码调试的方便程度而言:const常量可以进行调试的,define是不能进行调试的,因为在预编译阶段就已经替换掉了

14.extern "C"的用法

  • C++代码中调用C语言代码;
  • 在C++中的头文件中使用;
  • 在多个人协同开发时,可能有人擅长C语言,而有人擅长C++;

15.虚函数与纯虚函数

  • 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class)。
  • 虚函数可以被直接使用,也可以被子类(sub class)重载以后以多态的形式调用,而纯虚函数必须在子类(sub class)中实现该函数才可以使用,因为纯虚函数在基类(base class)只有声明而没有定义。
  • 虚函数和纯虚函数都可以在子类(sub class)中被重载,以多态的形式被调用。
  • 虚函数和纯虚函数通常存在于抽象基类(abstract base class -ABC)之中,被继承的子类重载,目的是提供一个统一的接口。
  • 虚函数的定义形式:virtual {method body}
    纯虚函数的定义形式:virtual { } = 0;
  • 在虚函数和纯虚函数的定义中不能有static标识符,原因很简单,被static修饰的函数在编译时候要求前期bind,然而虚函数却是动态绑定(run-time bind),而且被两者修饰的函数生命周期(life recycle)也不一样

16.能用纯虚函数的类声明对象么

  • 普通类具有成员函数,构造类的对象时,会对成员变量和成员函数分配内存。含有纯虚函数的类,定义了成员函数的地址是空,无法分配内存,该成员函数对类是没有意义的,失去了普通类的数据和方法绑定于同一对象中的意义,因此无法构造对象,只能通过派生类继承这些成员函数并实现,才能构造派生类对象。此时抽象类就起到了定义接口的作用。

17.何为进程?何为线程?两者有何区别?

  • 何为进程?
    进程是一个应用程序被操作系统拉起来加载到内存之后从开始执行到执行结束的这样一个过程。简单来说,进程是程序(应用程序,可执行文件)的一次执行。进程通常由程序、数据和进程控制块(PCB)组成。
    传统的进程有两个基本属性:可拥有资源的独立单位;可独立调度和分配的基本单位。对于这句话我的理解是:进程可以获取操作系统分配的资源,如内存等;进程可以参与操作系统的调度,参与CPU的竞争,得到分配的时间片,获得处理机(CPU)运行。
    进程在创建、撤销和切换中,系统必须为之付出较大的时空开销,因此在系统中开启的进程数不宜过多。
  • 何为线程?
    线程是进程中的一个实体,是被系统独立分配和调度的基本单位。也有说,线程是CPU可执行调度的最小单位。也就是说,进程本身并不能获取CPU时间,只有它的线程才可以。
    线程作为调度和分配的基本单位,进程作为独立分配资源的单位。我对这句话的理解是:线程参与操作系统的调度,参与CPU的竞争,得到分配的时间片,获得处理机(CPU)运行。而进程负责获取操作系统分配的资源,如内存。
    线程基本上不拥有资源,只拥有一点运行中必不可少的资源,它可与同属一个进程的其他线程共享进程所拥有的全部资源。
  • 进程和线程的区别?
    线程分为用户级线程和内核支持线程两类,用户级线程不依赖于内核,该类线程的创建、撤销和切换都不利用系统调用来实现;内核支持线程依赖于内核,即无论是在用户进程中的线程,还是在系统中的线程,它们的创建、撤销和切换都利用系统调用来实现。
    但是,与线程不同的是,无论是系统进程还是用户进程,在进行切换时,都要依赖于内核中的进程调度。因此,无论是什么进程都是与内核有关的,是在内核支持下进程切换的。尽管线程和进程表面上看起来相似,但是他们在本质上是不同的。
    进程至少必须有一个线程,通常将此线程称为主线程。进程要独立的占用系统资源(如内存),而同一进程的线程之间是共享资源的。进程本身并不能获取CPU时间,只有它的线程才

18.static关键字

  • 全局静态变量
    在全局变量前加上关键字static,全局变量就定义成一个全局静态变量.位于静态存储区,在整个程序运行期间一直存在。
    初始化:未经初始化的全局静态变量会被自动初始化为0;
    作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾。
  • 局部静态变量
    在局部变量之前加上关键字static,局部变量就成为一个局部静态变量。内存中的位置:静态存储区
    初始化:未经初始化的局部静态变量会被自动初始化为0;
    作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域结束。但是当局部静态变量离开作用域后,并没有销毁,而是仍然驻留在内存当中,只不过我们不能再对它进行访问,直到该函数再次被调用,并且值不变;
  • 静态函数
    在函数返回类型前加static,函数就定义为静态函数。函数的定义和声明在默认情况下都是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。
    函数的实现使用static修饰,那么这个函数只可在本cpp内使用,不会同其他cpp中的同名函数引起冲突;
  • 类的静态成员
    在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。对多个对象来说,静态数据成员只存储一处,供所有对象共用。
  • 类的静态函数
    静态成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象成员。因此,对静态成员的引用不需要用对象名。
    在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员(这点非常重要)。如果静态成员函数中要引用非静态成员时,可通过对象来引用。**从中可看出,调用静态成员函数使用如下格式:<类名>::<静态成员函数名>(<参数表>);

19.C语言中量的存储位置

  • 栈:就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。

  • 堆:就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

  • 全局存储区(静态存储区):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。

  • 常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。

  • 程序代码区―存放函数体的二进制代码

20. const 有什么用途

  • 定义只读变量,即常量
  • 修饰函数的参数和函数的返回值
  • 修饰函数的定义体,这里的函数为类的成员函数,被const修饰的成员函数代表不修改成员变量的值

21.左值 与 右值 以及 左值引用 右值引用

  • 左值是可寻址的变量,有持久性;
    右值一般是不可寻址的常量,或在表达式求值过程中创建的无名临时对象,短暂性的。
    左值可以被修改,而右值一般不能,有例外(当定义了右值的右值引用时可以修改)

  • C++的表达式要么是左值,要么是右值。左值表达式的结果一般为一个对象或者一个函数。
    当一个对象被当做右值使用的时候,用的是内容。当一个对象作为左值使用的时候用的是对象的身份(对象在内存中的位置)。

  • 左值引用和右值引用
    左值引用:引用一个对象;传统的C++引用被称为左值引用。
    右值引用:就是必须绑定到右值的引用,C++11中右值引用可以实现“移动语义”,通过 && 获得右值引用。通过右值引用可以获取地址,该地址表示临时对象的存储位置。

int x = 6; // x是左值,6是右值
int &y = x; // 左值引用,y引用x

int &z1 = x * 6; // 错误,x*6是一个右值
const int &z2 =  x * 6; // 正确,可以将一个const引用绑定到一个右值

int &&z3 = x * 6; // 正确,右值引用
int &&z4 = x; // 错误,x是一个左值
  • C++11通过引入右值引用来优化性能,具体来说是通过移动语义来避免无谓的拷贝问题,通过move语义来将临时生成的左值中无法替代的资源无代价的转移到另一个对象中去,通过完美转发来解决不能按照参数实际类型来转发的问题。
  • 右值值引用通常不能绑定任何左值,要想绑定一个左值到右值引用,通常需要通过std::move()将左值强制转换为右值。

22. 值传递,地址传递,引用传递的区别

  • 值传递
    将实参的值(a、b)复制到形参(m、n)相应的存储单元中,即形参和实参分别占用不同的存储单元。
    值传递的特点是单向传递,即主调函数被调用时给形参分配存储单元,把实参的值传递给形参,在调用结束后,形参的存储单元被释放,而形参值的任何变化都不会影响到实参的值,实参的存储单元仍保留并维持数值不变。

  • 地址传递
    所谓的地址传递,指的就是函数的参数是数组名或者指针。传递的是数组的首地址或指针的值,而形参接收到的是实参的地址,即指向实参的存储单元,形参和实参占用相同的存储单元,所以形参和实参是相同的。形参并不存在存储空间,编译系统不为形参数组分配内存。因此在数组名或指针作函数参数时所进行的传送只是地址传送,形参在取得该地址之后,与实参共同拥有一段内存空间,形参的变化也就是实参的变化。

  • 引用传递
    形参相当于是实参的“别名”,对形参的操作其实就是对实参的操作,在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。形参的地址是实参地址的映射,即拥有不同的储存空间但是里面存放的地址相同。
    被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量,和地址传递差不多。
    23. resize和reserve区别

  • 首先分清楚两个概念:
    capacity:该值在容器初始化时赋值,指的是容器能够容纳的最大的元素的个数。还不能通过下标等访问,因为此时容器中还没有创建任何对象。size:指的是此时容器中实际的元素个数。可以通过下标访问0-(size-1)范围内的对象。
    就比如说一个瓶子的容量是600ml,意思是它最多可以装600ml,而不是说现在瓶子里就有600ml,这里的600ml就相当于capacity;而说现在瓶子的size为300ml,就是说它真的装有300ml。

  • 那么就可以分清楚resize和reserve的区别了:
    reserve是设置了capacity的值,比如reserve(20),表示该容器最大容量为20,但此时容器内还没有任何对象,也不能通过下标访问。resize既分配了空间,也创建了对象,可以通过下标访问。

  • reserve只修改capacity大小,不修改size大小,resize既修改capacity大小,也修改size大小。
    reserve是容器预留空间,但并不真正创建元素对象,在创建对象之前,不能引用容器内的元素,因此当加入新的元素时,需要用push_back()/insert()函数。
    resize是改变容器的大小,并且创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。

  • 再者,两个函数的形式是有区别的,reserve函数之后一个参数,即需要预留的容器的空间;resize函数可以有两个参数,第一个参数是容器新的大小,第二个参数是要加入容器中的新元素,如果这个参数被省略,那么就调用元素对象的默认构造函数。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值