1.C++面向对象的三大特征?

1)封装:将客观事物封装成抽象的类,并且设计者可以对类的成员进行访问控制权限控制.

这样一方面可以做到数据的隐藏,保护数据安全;另一方面,封装可以修改类的内部

实现而不用修改调用了该类的用户的代码.同时封装还有利于代码的方便复用;

2)继承:a.继承具有这样一种功能,它可以使用现有类的所有功能;并且可以在不重新编写原有

类的情况下对类的功能进行扩展.

继承的过程是一般到特殊的过程,即是它们是is-a的关系;

基类或父类是一般,而子类或派生类是基类的特殊表现;

要实现继承可以通过继承和组合来实现;

b.广义上的继承分成三大类:

实现继承:使用基类的属性和方法而无需额外编码的能力;

接口继承:接口继承是指仅使用基类的属性和方法的名称,而具体的实现子类必须自己完成的能力;

可视继承:子窗体(类)使用父窗体(类)的外观和实现代码的能力;

3)多态:a.多态的实现分成两种,一种是编译时的多态,主要是通过函数重载和运算符重载来实现的,是通过静态联编实现的;

另外一种是运行时多态,主要是通过函数覆盖来实现的,它需要满足3个条件:基类函数必须是虚函数,并且基类的指针

或引用指向子类的时候,当子类中对原有的虚函数进行重新定义之后形成一个更加严格的重载版本的时候,就会形成

多态;它是通过动态联编实现的;

b.运行时的多态可以让基类的指针或引用指向不同的对象的时候表现出来不同的特性;

2.简述C/C++程序编译时的内存分配情况

1)一般一个c/c++程序编译的时候内存布局如下(地址从低到高的顺序)

a.代码区:存放程序的二进制代码.

b.常量区:这个区和代码区的距离很近,主要存放一些非局部常量值和字符串字面值,一般不允许修改,程序结束由系统释放;

具有常属性并且初始化的全局和静态变量也放在这个区.

c.数据区:赋过初值的且不具有常属性的静态和全局变量在数据区.它和BSS段统称为静态区;程序结束后由系统释放;

d.BSS段:没有初始化的静态和全局变量;进程一旦被加载这个区所有的数据都被清0;

e.堆区:   动态分配的内存;由程序员分配和释放,程序结束的时候如果没有释放,则由OS回收;

f.栈区:    由编译器自动分配和释放,不使用的时候会自动的释放.主要用来存放非静态的局部变量,函数的参数和返回值,

临时变量等.

g.命令行参数和环境变量区;

下面是对应一段经典的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //unix下的头文件
const int const_global = ; //常全局变量
int init_global = ; //初始化的全局变量
int uninit_global; //未初始化的全局白能量 int main(int argc,char * argv[])
{
const static int const_static = ;//常属性的静态变量,不可以被赋值,初始化
static int init_static = ; //初始化静态变量
static int uninit_static; //未初始化静态变量
const int const_local = ; // 常属性的局部变量
int prev_local = ;//前局部变量
int next_local = ;//后局部变量
int* prev_heap = malloc(sizeof(int));//前面分配的堆变量
int* next_heap = malloc(sizeof(int));//后面分配的堆变量
const char* literal = "literal"; //字符串字面值,字面值常量
extern char** environ; // 环境变量 printf("----地址最高断命令行参数和环境变量-------\n");
printf(" 环境变量:%p\n",environ);
printf(" 命令行参数:%p\n",argv);
printf("---------------栈区-----------------------\n");
printf(" 常局部变量:%p\n",&const_local);
printf(" 前局部变量:%p\n",&prev_local);
printf(" 后局部变量:%p\n",&next_local);
printf("--------------------堆--------------------\n");
printf(" 前堆变量:%p\n",prev_heap);
printf(" 后堆变量:%p\n",next_heap);
printf("--------------------BSS--------------------\n");
printf("未初始化全局变量:%p\n",&uninit_global);
printf("未初始化静态变量:%p\n",&uninit_static);
printf("----------------数据------------------------\n");
printf(" 初始化全局变量:%p\n",&init_static);
printf(" 初始化全局变量:%p\n",&init_global);
printf("----------------代码区----------------------\n");
printf(" 常静态变量:%p\n",&const_static);
printf(" 字面值常量:%p\n",&literal);
printf(" 常全局变量:%p\n",&const_global);
printf(" 函数:%p\n",main);
return ;
}

2)从上面可以看出c/c++的内存分配方式主要有三种?

a.从静态存储区域分配:

内存在程序编译时已经分配好,这块内存在程序的整个运行期间都存在.

速度快,不容易出错.因为由系统会善后.

b.在栈上分配内存:

在执行函数的时候,函数内非静态局部变量的存储单元都是在栈上创建,函数执行

结束的时候这些存储单元自动被释放.栈内存分配内置于处理器的指令集中,效率

很高但是分配的内容有限.

c.从堆中分配内存:

即是动态分配内存.程序在运行的时候使用malloc/new申请任意大小的内存,程序员

自己负责在何时用free/delete释放内存.动态内存的生存期由程序员决定,使用非常的

灵活.如果在堆上分配了内存,就有责任去回收它,否则运行程序会出现内存泄漏,另外

频繁的分配和释放不同大小的堆空间将会产生堆内碎片.不易管理;

3)堆和栈之间的主要的区别是什么?

a.管理方式不同:栈是由编译器自动分配和释放,使用方便;而对于堆来说,

分配和释放都必须由程序员来手动完成,不易管理,容易

造成内存泄漏和内存碎片.

b.可用内存空间不同:对于栈来说,它可用的内存空间比较小;而对于堆来说它可以使用的空间比栈要大的多.

c.能否产生碎片不同:由于栈采用的是后进先出的机制,所以栈空间没有内存碎片的产生;

而对于堆来说,由于频繁的使用new/delete势必会造成内存空间分配的不连续,从而

造成大量的碎片,使程序的效率降低.

d.生长方向不同:  对于堆来说,它一般是向上的;即是向着地址增加的方向增长;对于栈来说,它一般是向下的,

即向着地址减小的方向增长.

e.分配的方式不同:对于堆来说,它只能是动态分配的;而对于栈来说,它分为静态分配和动态分配;

静态分配由编译器来进行管理,而动态分配的栈和堆也是不一样的,动态分配的

栈由编译器进行释放,无需我们程序员来释放.

f.分配的效率不同:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:为栈分配专门的寄存器.

压栈和出栈都由专门的指令进行.因此它的效率会很高;

而堆则是由c/c++库函数实现的,机制是非常的负责的;例如要分配一块内存的时候,库

函数会利用特定的算法在堆内存中搜索可用大小的内存空间;如果没有足够大的内存

空间,就会调用系统功能去增加数据段的内存空间.这样才能得到足够大的可用的内存

空间,因此堆内存的分配的效率比栈要低得多.

4)new/malloc以及free/delete之间的区别?

a.new/delete是运算符,只能在C++中使用,它可以重载;mallloc/free是C的标准库函数,在C/C++中都可以使用.

b.对于非内部的数据类型的对象而言,光用malloc/free是无法满足动态对象的要求的.对象在创建的时候需要

执行构造函数,对象在消亡之前需要执行析构函数.而molloc/free是库函数而不是运算符,不在编译器的控制

范围之内,编译器不能将执行构造函数和析构函数的任务强加给malloc/free.因此C++需要一个能够完成动态

分配内存和初始化的new,以及一个能够完成清理和释放内存的运算符delete.

c.new的返回值是指定类型的指针,可以自动的计算所需要分配的内存大小.而malloc的返回值是一个void类型

的指针,我们在使用的时候要进行强制类型转换,并且分配的大小也要程序员手动的计算.

d.new/delete完全覆盖了malloc/free的功能,只所以还要保留malloc/free,是因为我们的C++程序有时要调用用C编写的

而C中又没有new/delete,只能使用malloc/free.

3.指针和引用之间的区别和联系?

联系:

a.指针和引用本质上都是地址的概念,引用在内部其实是用const指针来实现的.

b.给函数传递参数的时候,一级指针和引用作为函数参数的时候可以达到相同的效果.

c.指针的大部分效果都可以通过引用来实现。

d.二级指针作为参数的时候就是希望在函数的内部修改指针的指向.这个时候利用指针

的引用可以达到同样的效果.

区别:

a.定义引用的时候必须初始化,定义指针的时候可以不初始化.

b.引用不能引用空,但是指针可以指向空.

c.引用的关系一旦确定,就无法改变;引用永远指向的是用来对它初始化的对象;而非常属性的指针是可以改变指向的.

d.指针是一个实体变量,在32位操作系统上面都是4个字节.而引用只是一个别名,其大小和其应用的对象的类型有关系.

e.有指向指针的指针,但是没有引用引用的引用;因为引用一旦建立,它就表示初始化它的对象.

f.有引用指针的引用,但是没有指向引用的指针;

g.有指针数组,但是没有引用数组,但是有数组的引用.

下面是一段代码非常的全面:

#include <iostream>
using namespace std;
void foo(int a[])/*这个地方传递的是数组的首地址*/
{
cout << sizeof(a)/sizeof(a[]) << endl;
}
void bar(int (&a)[])/*这里传参的时候就是数组的整体*/
{
cout << sizeof(a)/sizeof(a[]) << endl;
}
int main(void)
{
int a;
int* p = &a;
int** pp = &p;/*存在指向指针的指针*/
int& r = a;
int&& rr = r;/*error没有引用引用的引用*/
int*& rp = p; /*有引用指针的引用(指针引用)*/
int&* pr = &r; /*没有指向引用的指针(引用指针)*/
int x, y, z;
int* pa[] = {&x,&y,&z};/*指针数组*/
int& ra[] = {x,y,z};/*引用数组是不存在的因为引用不是一个实体*/
int arr[] = {};
int (&ar)[] = arr;/*数组引用(先近后远,先右后左)*/
foo(arr);/*这里传递的是数组的第一个元素的首地址*/
cout << sizeof(arr)/sizeof(arr[]) << endl;
/*这里的数组名代表的是真个数组*/
int (*parr)[] = &arr;/*对数组名取地址得到的是一个数组指针
这个时候arr代表的是数组的整体;*/
bar(arr);/*这里传递的就是数组的整体*/
return ;
}

c/c++面试题(5)(c++重要的概念详解)的更多相关文章

  1. React 精要面试题讲解(二) 组件间通信详解

    单向数据流与组件间通信 上文我们已经讲述过,react 单向数据流的原理和简单模拟实现.结合上文中的代码,我们来进行这节面试题的讲解: react中的组件间通信. 那么,首先我们把看上文中的原生js代 ...

  2. 面试题:MySQL性能调优——索引详解与索引的优化 没用

    ——索引优化,可以说是数据库相关优化.理解尤其是查询优化中最常用的优化手段之一.所以,只有深入索引的实现原理.存储方式.不同索引间区别,才能设计或使用最优的索引,最大幅度的提升查询效率! 一.BTre ...

  3. 面试题:J2EE中web.xml配置文件详解 背1

    一.web.xml是什么 web.xml学名叫部署描述符文件,是在Servlet规范中定义的,是Web应用的配置文件,是Web应用的基础. 二.web.xml加载流程 总的来说:ServletCont ...

  4. 大厂高频面试题Spring Bean生命周期最详解

    Spring作为当前Java最流行.最强大的轻量级框架.Spring Bean的生命周期也是面试高频题,了解Spring Bean周期也能更好地帮助我们解决日常开发中的问题.程序员应该都知道Sprin ...

  5. 猫哥网络编程系列:详解 BAT 面试题

    从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...

  6. 李洪强iOS经典面试题156 - Runtime详解(面试必备)

    李洪强iOS经典面试题156 - Runtime详解(面试必备)   一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C ...

  7. 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)

    李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...

  8. Java面试题04-final关键字详解

    Java面试题04-final关键字详解 本篇博客将会讨论java中final关键字的含义,以及final用在什么地方,感觉看书总会有一些模糊,而且解释的不是很清楚,在此做个总结,以备准备面试的时候查 ...

  9. 《招一个靠谱的移动开发》iOS面试题及详解(下篇)

    iOS面试知识点 现在进入本篇的正题.本篇的面试题是我认为比较好的iOS开发基础知识点,希望大家看过这后在理解的基础上掌握而不是死记硬背.死记硬背很快也会忘记的. 1 iOS基础 1.1 父类实现深拷 ...

随机推荐

  1. .Net程序员安卓学习之路4:使用xutils Get Post数据

    前面使用了一些网络上找来的类进行网络访问,后来发现了安卓开发中有一个国人写的类库xutils比较全面,也比较经典,故后续使用xutils类库进行记录. 本例服务端使用WCF来实现,写好的WCF服务端在 ...

  2. DirectUI 收集资料

    1.[ZsUI]一步一步写个DirectUI.[连载贴] (http://tieba.baidu.com/p/1625954225) ps: 虽然是vb写的,也很简陋,不过有代码,并且作者每节都给出了 ...

  3. Codeforces 749B:Parallelogram is Back(计算几何)

    http://codeforces.com/problemset/problem/749/B 题意:已知平行四边形三个顶点,求另外一个顶点可能的位置. 思路:用向量来做. #include <c ...

  4. C# 使用 Abot 实现 爬虫 抓取网页信息 源码下载

    下载地址 ** dome **

  5. HTML5正则表单式验证电子邮件

    <input type="text" title="email" required pattern="[^@]+@[^@]+\.[a-zA-Z] ...

  6. 添加一个DataSet

    /// <summary> /// 返回状态数据 /// </summary> /// <param name="values"></pa ...

  7. 如何使用VS2013对C++进行编程

    https://msdn.microsoft.com/zh-cn/library/bb384842.aspx

  8. WPF上Arc Lisence的有关问题

    WPF下Arc Lisence的问题代码如下: using System; using System.Collections.Generic; using System.Configuration; ...

  9. lambda的使用ret = filter(lambda x : x > 22 ,[11,22,33,44])

    #!/usr/bin/env python #def f1(x) : # return x > 22 ret = filter(lambda x : x > 22 ,[11,22,33,4 ...

  10. 遗传算法在JobShop中的应用研究(part 2:编码)

    编码 在上一篇博客中我们讨论了车间调度问题的编码,具体说就是根据工件的个数和每个工件的工序数来生成12122这样的数字排列,具体的说一个工件包含多少道工序,那么这个工件的编号就出现多少次.从12122 ...