C++面试题 笔记

1、 static关键字 
    全局静态变量 局部静态变量 静态函数 类的静态成员 类的静态函数
2、c c++  区别 
          c++面向对象  c面向过程  c++安全 强制类型转换  范式编程 
          模板类 函数模板
3、四种转换  const_cast  static_cast  dynamic_cast  reinterpret_cast
         为什么不使用C的强制转换? 转化不明确 不能错误检查 易出错
4、指针和引用 
        有无空间 sizeof  初始化 const  被改变 多级 ++ 动态分配内存
5、四个智能指针 auto_ptr  weak_ptr share_ptr unique_ptr 1废了
6、野指针指向一个已删除的对象或未申请访问受限内存区域的指针。
7、智能指针的内存泄漏 
          两个对象相互使用一个shared_ptr 成员变量指向对方
         造成循环引用 引用计数失效   用weak_ptr 解决内存泄漏 不会改
         变引用计数的值,类似普通指针,但不指向引用计数的共享内存
         可以检测到对象是否释放,避免非法访问
7、 为什么析构函数必须是虚函数?为什么 C++默认的析构函数不是虚函数
         将可能会被继承的父类的析构函数设置为虚函数,可以保证当我们 new 一个子类,然后使用
    基类指针指向该子类对象,释放基类指针时可以释放掉子类的空间,防止内存泄漏。
    C++默认的析构函数不是虚函数是因为虚函数需要额外的虚函数表和虚表指针,占用额外的
    内存。而对于不会被继承的类来说,其析构函数如果是虚函数,就会浪费内存。因此 C++默认的
    析构函数不是虚函数,而是只有当需要当作父类时,设置为虚函数。
8、函数指针
9、fork()vfork()exec()
10、析构函数作用  类析构顺序 派生类析构函数->对象成员析构函数->基类析构函数
11、静态函数和虚函数  静态函数在编译时期就确定了运行的时机,虚函数在运行的时候动态绑定的
    虚函数用了虚函数表的机制,调用的时候会增加一次内存开销。
12、重载和覆盖 重载:两个函数名相同参数列表不同 返回值类型也得相同 
          重写:派生类继承了基类,基类中的函数是虚函数,在子类中重新定义了这个虚函数,属于重写
13、多态的实现:静态多态和动态多态
14、    ++i 先自增 再返回  i++ 先返回i 在自增
    效率不同:后置++执行速度比前置的慢
    i++ 不能作为左值,而++i 可以
    两者都不是原子操作
15、RTTI 运行时类型检查 dynamic 和typeid
16、C语言如何进行函数调用 每个函数有函数栈 栈内进行函数执行过程 如swap(a,b)函数执行之前会将&b和&a的地址压栈
17、野指针 指向的位置是未知的 释放内存后不及时制空 依旧指向该内存会出现非法访问  
    避免  初始化制空   申请内存后判空  指针释放后制空 使用智能指针 
18、         new是操作符,而malloc是函数。
    new在调用的时候先分配内存,在调用构造函数,释放的时候调用析构函数;而malloc没有构造函数和析构函数。
    malloc需要给定申请内存的大小,返回的指针需要强转;new会调用构造函数,不用指定内存的大小,返回指针不用强转。
    new可以被重载;malloc不行
    new分配内存更直接和安全。
    new发生错误抛出异常,malloc返回null
    
    malloc的底层实现  开辟空间小于128k调用    brk()函数 大于128k 调用mmp()  malloc 采用的是内存池的管理方式以减少内存碎片 先申请一个较大的空间
    作为堆区然后将堆区分为多个内存块,直接从堆区分配一块合适的空闲块。采用隐式的链表将所有的空闲块连接起来,每一个内存块记录了未分配、连续的内存块。
    
    new的底层实现         1、 创建一个新的对象
            2、将构造函数的作用域赋值给这个新的对象
            3、执行构造函数中的代码
            4、返回新对象
19、const和define
    const生效于 编译阶段 define 生效于  预处理
    const定义的常量是占用空间的 define 运行时是直接的操作数不会占用内存
    const 常量是带类型的   define 不带类型 不利于类型检查
20、指针函数 是函数 返回值为指针  函数指针是指针 指向函数
21、使用指针的注意事项
    定义指针时,先初始化为NULL。
    用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。
    不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
    避免数字或指针的下标越界,特别要当心发生“多1”或者“少1”操作
    动态内存的申请与释放必须配对,防止内存泄漏
    用free或delete释放了内存之后,立即将指针设置为NULL,防止“野指针”
22、内联和普通函数区别
    内联不需要调用避免了开销,不需要寻址
    内联函数有要求需要代码简单 不能包含复杂的结构语句

      内联的作用 调用时将调用表达式替换成内联函数体
      内联函数定义必须在内联函数第一次调用之前
23、C++几种传值方式
    值传递        行参在函数体内变化不会影响实参的变化
    引用传递      形参在函数体内变化会影响实参的变化
    指针传递      指针指向没有改变的前提下形参在函数体内发生变化会影响实参的值
       值传递用于对象时,整个对象会拷贝一个副本,这样效率低;而引用传递用于对象时,不发生拷贝行为,只是绑定对象,更高效;指针传递同理,但不如引用传递安全。
           引用在定义时就与变量绑定了,而指针不一定,指针在定义后没有初始化就是野指针。
                   引用与被引用的变量是同一个地址,使引用不用进行地址操作,这样使地址是不可修改的,使访问更加安全。
24、const * 和* const
    const *是常量指针 *const 是指针常量
    

    

    

    
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值