alin的学习之路:面试题 C/C++相关

alin的学习之路:面试题 C/C++相关

  • c++虚函数原理

    • 加上virtual关键字后,父类的结构发生了改变,在原有的基础上增加了一个指向虚函数表的指针
    • 虚函数表中存放的是虚函数的地址,父类的地址结构中放的是这个虚函数的地址
    • 当子类重写父类的虚函数时,虚函数表中的函数地址发生了改变,变为了重写的函数的地址,从而可以对其进行调用
  • 智能指针

    • 智能指针是存储指向动态分配(堆)对象指针的类。能够在适当的时间自动删除指向的对象。智能指针在面对异常的时候格外有用,因为他们能够确保正确的销毁动态分配的对象。他们也可以用于跟踪被多用户共享的动态分配对象。
    • 使用智能指针,从而实现指针指向的对象的共享。
    • 引入智能指针可以防止出现悬垂指针的情况,一般是把指针封装到一个称之为智能指针类中,这个类中另外还封装了一个使用计数器,对指针的复制等操作将导致该计数器的值加1,对指针的delete操作则会减1,值为0时,指针为NULL
  • c语言如何实现c++对象以及私有成员

    • 使用struct结构体实现封装,类中的一些方法可以使用函数指针变量来代替
    • 私有成员可以使用void*对结构体变量进行修饰,从而隐藏掉其真实的类型,达到私有成员的效果,真实的类型只有开发者才知道
  • c++多态实现

    • C++的多态分为静态多态和动态多态
    • 静态多态和动态多态的区别就是函数地址是早绑定(静态联编)还是晚绑定(动态联编)。如果函数的调用,在编译阶段就可以确定函数的调用地址,并产生代码,就是静态多态(编译时多态),就是说地址是早绑定的。而如果函数的调用地址不能编译不能在编译期间确定,而需要在运行时才能决定,这这就属于晚绑定(动态多态,运行时多态)。
    • 实现方法:子类重写父类的虚函数,地址绑定称为子类的函数地址
  • new和malloc的区别以及底层实现原理

    • 区别
      • new带有内置的长度计算、类型转换和安全检查。
      • new 当创建一个对象数组的时候,必须对数组中的每一个对象调用构造函数
      • new 对应 delete ,malloc 对应 free
      • new 是一个运算符 malloc 是一个函数
      • 返回值:new返回对应类型指针,malloc返回void*
      • 分配失败:new 分配失败时会抛出异常,malloc是返回NULL
    • 底层实现:
      • new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。
      • malloc 调用时,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。
  • STL中的vector怎么扩容

    • 底层是使用realloc
    • 扩容机制是根据特定的算法来的,每当容量剩余达到一定数量时,就会根据当前容量进行扩容
  • 虚函数指针的初始化过程

    • 在基类的构造函数被调用之后,自定义代码调用之前
    • 构造过程中,首先在基类的构造函数中,会把虚函数指针初始化为指向基类的虚函数表,然后,在子类构造函数中又覆盖为指向子类的虚函数表,层层覆盖,最后虚函数指针会正确指向构造的类的虚函数表。
    • 由于虚函数指针初始化代码是在自定义代码之前,这意味着我们可以在自定义代码的构造函数中调用该类的虚函数。
  • c++11原子变量介绍

    • atomics
  • c++11特性有哪些,说用过的

    • lambda表达式
    • 模板技术 template<class T>
  • 怎么理解重载与重写

    • 重载是不同的函数
    • 重写是指子类继承父类后的重写
  • 怎么理解c++中的static关键字

    • 只初始化一次
  • vector和list 的区别

    • vector是连续存储的数组
    • list是链表形式,数据的存储内存地址不连续
  • c++的内存分配

    • 在C++中内存分为5个区,分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
    • **堆:**堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。
    • **栈:**在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
    • **自由存储区:**自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区
    • **全局/静态存储区:**这块内存是在程序编译的时候就已经分配好的,在程序整个运行期间都存在。例如全局变量,静态变量。
    • **常量存储区:**这是一块比较特殊的存储区,他们里面存放的是常量(const),不允许修改。
  • map与set的底层实现

    • 红黑树

    • map和set容器内的所有元素都是以节点方式来存储的,其节点结构和链表类似,指向父节点和子节点。

      因此,在插入的时候只需要稍作变换,把节点的指针指向新的节点就可以了。删除的时候类似,稍作变换后吧指向删除节点的节点的指针指向其他的节点就可以了。
      这其中,只涉及到指针的转换,而没有涉及到内存的移动。

  • 类静态变量的初始化

    • 需要在类内声明,类外初始化
  • 析构函数可以是虚函数?为什么

    • 析构函数可以为虚函数,也可以不为虚函数。(更多的时候不为虚函数)。默认不为虚函数。
      设计析构函数为虚函数,主要是考虑到继承。

    • 当A为基类,B为A的继承类,考虑如下情况:
      A *p = new B();
      .....
      delete p;
      
      此时如果析构函数不是虚函数,那么delete p会执行A的析构函数,而不是B的,这样会造成B的函数资源没有释放
      
  • 深拷贝与浅拷贝

    • 深拷贝和浅拷贝的问题主要发生在指针上
    • 浅拷贝指的是只拷贝了指针的值,而并未拷贝指针指向的内容
    • 深拷贝指的是重新申请一块内容,并且将原指针指向的内容拷贝一份到新的指针里面
  • 指针常量,常量指针的区别

    • 指针常量 * const :指针的指向不能发生修改。
    • 常量指针 const * :指针指向的值不能直接发生修改。
  • 指针与引用的区别

    • 引用的底层是操作受限的指针,不能修改指向等等。

    • 指针是一个变量,存储的是指向内容的地址。引用相当于是一个变量的别名。

    • 引用不可以为空,创建必须初始化。指针可以为空,可以在需要使用的时候进行初始化。

    • 指针可以有多级,引用只有一级。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值