面试 -- C++简答题

C++简答题

1.C++中什么数据分配在栈或堆,静态存储区以及常量存储区中?
堆区是动态分配的数据 通过malloc及new来申请动态分配存储
栈区是存储系统自动分配空间的变量, 如局部变量
静态存储区存放全局变量和静态变量, 未被初始化或初始化为0的存放在bss段, 非0全局变量的存在数据段的数据区 . 程序结束后有系统释放
常量存储区存放常量字符串就是放在这里的。 程序结束后由系统释放
程序代码区—存放函数体的二进制代码

2.C++编译器自动为类产生的四个缺省函数是什么?
默认构造 , 拷贝构造 ,析构 , =运算符函数, &运算符函数

3.我们可以用static修饰一个类的成员函数,也可以用const修饰类的而成员函数请问:能不能同时用const和static修饰类的成员函数? 并进行说明.
不可以 const修饰的成员函数, 为了保证函数不能改变成员属性, 添加隐藏参数 const this * , 但static修饰的成员函数, 没有this指针, 此时const 和static 的用法是冲突的.

4.在C++中,构造函数是没有返回值的,那么该如何处理构造函数中可能发生的错误(例如资源分配失败)?
异常或者assert断言

5.请简述C/C++语言中栈空间和堆空间的主要区别.
栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
堆区(heap)一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
区别主要体现在下面几个方面
1、内存分配方面:
堆:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式是类似于链表。可能用到的关键字如下:new、malloc、delete、free等等。
栈:由编译器(Compiler)自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、申请方式方面:
堆:需要程序员自己申请,并指明大小。在c中malloc函数如p1 = (char *)malloc(10);在C++中用new运算符,但是注意p1、p2本身是在栈中的。因为他们还是可以认为是局部变量。
栈:由系统自动分配。 例如,声明在函数中一个局部变量 int b;系统自动在栈中为b开辟空间。
3、系统响应方面:
堆:操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete语句才能正确的释放本内存空间。另外由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
4、大小限制方面:
堆:是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
栈:在Windows下, 栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是固定的(是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
5、效率方面:
堆:是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便,另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。
栈:由系统自动分配,速度较快。但程序员是无法控制的。
6、存放内容方面:
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
栈:在函数调用时第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈,然后是函数中的局部变量。 注意: 静态变量是不入栈的。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
7、存取效率方面:
堆:char *s1 = “Hellow Word”;是在编译时就确定的;
栈:char s1[] = “Hellow Word”; 是在运行时赋值的;用数组比用指针速度要快一些,因为指针在底层汇编中需要用edx寄存器中转一下,而数组在栈上直接读取。

6.C++处理异常可以有两种方式,一种是throw异常,一种是在函数中return 错误码.你怎么理解这两种方法的优劣.
throw 异常要优于return错误码
throw异常就像中断机制, 对异常能够单独操作 , 确保程序的稳定性
return 错误码, 通过错误码进行判断 , 根据错误码处理错误.
throw是专门处理异常的, 代码写起来, 结构比较容易. return 错误码, 异常处理部分需要自己写, 结构更复杂.

7.为什么析构函数建议加virtual属性
delete一个指向基类的指针时,该基类指针指向派生类实例,如果基类的析构函数不加virtual属性,会导致无法调用派生类的析构函数,会造成内存泄漏

8.拷贝构造函数的形参形式是什么样子的?为什么采用这种形式?什么情况下会被调用?
1)函数名为类名,参数为类对象的引用.
2)拷贝构造的实参是对象,那么形参可能是对象或对象的引用,形参如果是对象,那么在调用函数时要先对形参进行初始化又是一次拷贝构造,从而陷入死循环;那么形参应该是对象的引用。拷贝构造会通过类对象的引用将对象的属性值赋值给新对象, 因此使用引用
3)当一个对象通过另一个对象初始化时, 调用函数形参是该类对象时 , 返回类对象产生临时变量时。

9.在C++的语法中有友元函数friend(一个类的成员函数可以作为另一个类的友元,前者可以访问后者对象的私有成员)。但后期的高级语言java和C#
却没有这方面的语法支持,为什么要去掉友元函数,谈谈你的理解。
虽然友元函数能够提高效率,表达简单、清晰,但是友元函数破环了封装机制,除非不得已的情况下才使用友元函数

10.简单说明面向对象的特性及重要性。
面向对象的特性:封装,继承,多态
继承: 派生类可以从它的基类那里继承方法和属性 , 提高代码复用性
封装: 把过程和数据包围起来, 保证了模块具有较好的独立性,使得程序维护修改较为容易.
多态: 多态性是指允许不同类的对象对同一消息作出响应, 多态性语言具有灵活、抽象、行为共享、代码共享的优势

11.(1)指针和引用的区别是什么
(2)malloc/free & new/delete的区别是什么
(3)struct 与 class 的区别是什么
1)1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。
(2)指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)
(3)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化。
(4)指针的值在初始化后可以改变,即指向其它的存储

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SS_zico

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值