您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 招聘面试 > 王牌7 Visual C++常见面试题
王牌71一、常见试题1.重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?从定义上来说:重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。重写:是指子类重新定义父类虚函数的方法。从实现原理上来说:重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:functionfunc(p:integer):integer;和functionfunc(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!重写:和多态真正相关。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)。2.main函数执行以前,还会执行什么代码?全局对象的构造函数会在main函数之前执行。3.简述数组与指针的区别?数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。修改内容上的差别:chara[]=“hello”;a[0]=‘X’;char*p=“world”;//注意p指向常量字符串p[0]=‘X’;//编译器不能发现该错误,运行时错误2用运算符sizeof可以计算出数组的容量(字节数)。sizeof(p)p为指针得到的是一个指针变量的字节数,而不是p所指的内存容量。C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。chara[]=helloworld;char*p=a;coutnext);}returnhead;}4.引用和指针的区别?引用和指针有如下三种区别:1.引用必须在声明时初始化,而指针不用;2.对于NULL不能引用,而指针可以指向NULL;3.引用一旦声明,对象不能改变;而指针可以随时改变指向的对象。引用能做到的,指针也可以,但指针更危险;5.虚函数的本质和实现机制虚函数的本质是通过基类访问派生类定义的函数。虚函数只能借助于指针或者引用来达到多态效果。6.请问C++的类和C里面的struct有什么区别?c++中的类具有成员保护功能,并且具有继承,多态这类oo特点,而c里的struct没有7.struct和class的区别?struct的成员默认是公有的,而类的成员默认是私有的。struct和class在其他方面是功能相当的。大垛数的开发者感到类和结构有很大的差别。感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位,而类就象活的并且可靠的社会成员,它有智能服务,有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为,那么只有在你的类有很少的方法并且有公有数据(这种事情在良好设计的系统中是存在的!)时,你也许应该使用struct关键字,否则,你应该使用class关键字。王牌738.static有什么用途?(请至少说明两种)限制变量的作用域、设置变量的存储域。9.全局变量和局部变量在内存中是否有区别?如果有,是什么区别?全局变量储存在静态数据区,局部变量在堆栈中。10.队列和栈有什么区别?队列先进先出,栈后进先出11.类成员函数的重载、覆盖和隐藏区别?a.成员函数被重载的特征:(1)相同的范围(在同一个类中);(2)函数名字相同;(3)参数不同;(4)virtual关键字可有可无。b.覆盖是指派生类函数覆盖基类函数,特征是:(1)不同的范围(分别位于派生类与基类);(2)函数名字相同;(3)参数相同;(4)基类函数必须有virtual关键字。c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)12.如何打印出当前源文件的文件名以及源文件的当前行号?cout__FILE__;cout__LINE__;__FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的413.有哪几种情况只能用intializationlist而不能用assignment?当类中含有const、reference成员变量;基类的构造函数都需要初始化表。14.如何判断一段程序是由C编译程序还是由C++编译程序编译的?#ifdef__cpluspluscoutc++;#elsecoutc;#endif15.请说出const与#define相比,有何优点?const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。16.结构与联合有和区别?结构和联合都是由多个不同的数据类型成员组成,但在任何同一时刻,联合中只存放了一个被选中的成员(所有成员共用一块地址空间),而结构的所有成员都存在(不同成员的存放地址不同)。对于联合的不同成员赋值,将会对其它成员重写,原来成员的值就不存在了,而对于结构的不同成员赋值是互不影响的。17.面向对象的三个基本特征,并简单叙述之?封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private,protected,public)继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=接口继承以及纯虚函数)构成了功能复用的两种方式。多态:是将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。王牌7518.*p++自增p还是p所指向的变量?后縀++和--操作符本质上比前縀一元操作符的优先级高,因此*p++和*(p++)等价,它自增p并返回p自增之前所指向的值。要自增p指向的值,则使用(*p)++,如果副作用的顺序无关紧要也可以使用++*p。19.Newdelete与mallocfree的联系与区别?都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new会自动调用对象的构造函数。delete会调用对象的destructor,而free不会调用对象的destructor.20.请讲一讲析构函数和虚函数的用法和作用?析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载。知识在类对象生命期结束的时候,由系统自动调用释放在构造函数中分配的资源。这种在运行时,能依据其类型确认调用那个函数的能力称为多态性,或称迟后联编。另:析构函数一般在对象撤消前做收尾工作,比如回收内存等工作,虚拟函数的功能是使子类可以用同名的函数对父类函数进行重载,并且在调用时自动调用子类重载函数,如果是纯虚函数,则纯粹是为了在子类重载时有个统一的命名而已。21.在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”?C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为:voidfoo(intx,inty);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。22.描述内存分配方式以及它们的区别?从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也昀多。623.delete与delete[]区别:delete只会调用一次析构函数,而delete[]会调用每一个成员的析构函数。当delete操作符用于数组时,它为每个数组元素调用析构函数,然后调用operatordelete来释放内存。delete与New配套,delete[]与new[]配套。MemTest*mTest1=newMemTest[10];MemTest*mTest2=newMemTest;int*pInt1=newint[10];int*pInt2=newint;delete[]pInt1;//-1-delete[]pInt2;//-2-delete[]mTest1;//-3-delete[]mTest2;//-4-在-4-处报错。这就说明:对于内建简单数据类型,delete和delete[]功能是相同的。对于自定义的复杂数据类型,delete和delete[]不能互用。delete[]删除一个数组,delete删除一个指针,简单来说,用new分配的内存用delete删除,用new[]分配的内存用delete[]删除,delete[]会调用数组元素的析构函数。内部数据类型没有析构函数,所以问题不大。如果你在用delete时没用括号,delete就会认为指向的是单个对象,否则,它就会认为指向的是一个数组24.子类析构时要调用父类的析构函数吗?析构函数调用的次序是先派生类的析构后基类的析构,也就是说在基类的的析构调用的时候,派生类的信息已经全部销毁了定义一个对象时先调用基类的构造函数、然后调用派生类的构造函数;析构的时候恰好相反:先调用派生类的析构函数、然后调用基类的析构函数25.什么是预编译?何时需要预编译?情况1:总是使用不经常改动的大型代码体。情况2:程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。26.求下面函数的返回值(微软)intfunc(x)王牌77{intcountx=0;while(x){countx++;x=x&(x-1);}returncountx;}将x转化为2进制,看含有的1的个数。假定x=9999。27.什么是“引用”?申明和使用“引用”要注意哪些问题?引用就是某个目标变量的“别名”(alias),对应用的操作与对变量直接操作效果完全相同。申明一个引用的时候,切记要对其进行初始化。引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。不能建立数组的引用。28.下面的函数实现在一个固定的数上加上一个数,有什么错误,改正intadd_n(intn){staticinti=100;i+=n;returni;}因为static使得i的值会保留上次的值。会导致调用一次i值累加。29.什么是COLORREF?我该怎样用它?COLORREF是一个32-bit整型数值,它代表了一种颜色。你可以使
本文标题:王牌7 Visual C++常见面试题
链接地址:https://www.777doc.com/doc-5373198 .html