C++知识点

C++三大特性

https://blog.csdn.net/qq_42021840/article/details/106141333

虚函数、虚指针、虚表

https://blog.csdn.net/qq_42021840/article/details/106150057

虚析构函数

用基类类型指针绑定派生类实例,析构的时候,如果基类析构函数不是虚函数,则只会析构基类,不会析构派生类对象,从而造成内存泄漏。为什么会出现这种现象呢,个人认为析构的时候如果没有虚函数的动态绑定功能,就只根据指针的类型来进行的,而不是根据指针绑定的对象来进行,所以只是调用了基类的析构函数;如果基类的析构函数是虚函数,则析构的时候就要根据指针绑定的对象来调用对应的析构函数了。

构造函数和析构函数中也不能调用虚函数,调用了也没用,一个是虚函数表指针还没有初始化好,一个是可能虚函数指针已经被析构了。

浅拷贝、深拷贝

深拷贝和浅拷贝最根本的区别就是是否真正的获取一个对象的复制体,而不是引用

 假如有两个对象A和B,B复制了A,修改A的时候,看B是否发生变化:

         如果B也跟着,说明是浅拷贝(修改的是堆中同一块内存)

         如果B没有改变,说明是深拷贝(修改的是堆内存中不同的值)

浅拷贝:增加了一个引用指针指向已存在的内存地址,如果原地址发生改变,那么浅拷贝出来的对象都会发生改变。

深拷贝:增加了一个引用指针指向申请的内存,用于存放复制的对象,如果原地址发生改变,并不会导致深拷贝出来的对象发生改变。

浅拷贝会导致对象结束时,释放两次析构函数,释放同一块内存。

当数据成员中有指针的时候必须要用深拷贝。

重载、重写 、重定义(隐藏)

重载 

          同一个可访问区域内具有不同参数列表(个数、类型、顺序)的同名函数,根据参数列表调用不同的函数,重载不关心函数的返回值类型

重写

         子类中对父类中的虚函数进行重新定义,其函数名、参数列表、返回值类型必须同基类中被重写的函数一致。

重定义

        子类的函数屏蔽了与其同名的基类函数,只要时同名函数,不管参数列表是否相同,基类都会被隐藏。

重载和重写的区别:

  • 范围区别:重写和被重写的函数在不同的类中,重载和被重载的函数在同一个类中
  • 参数区别:重写与被重写的函数列表一定相同,重载和被重载的函数列表一定不相同
  • virtual的区别:重写的基类必须要有virtual关键字,重载函数和被重载函数可以有virtual,也可以没有。

 类对象的内存分布

成员变量类型:staic和非staic。成员函数类型:static、非static和virtual。

C++内存格局有四个存储区:全局数据区、代码区、栈区、堆区。

全局数据区:全局变量、静态数据和常量。

代码区:类成员函数代码和非成员函数代码

栈区:为运行函数分配的局部变量、函数参数、返回数据、返回地址等。

堆区:动态申请的内存

在类的定义时

  • 类的成员函数放在代码区
  • 类的静态成员变量放在全局数据段
  • 非静态成员变量在类的实例内,实例在堆区或者栈区
  • 虚函数指针、虚基类指针在类的实例内,实例在堆区或者栈区   
  • 虚表在只读数据区

一个类实例的内存分布:

  1. 有虚函数的类中,虚函数指针永远时第一成员变量
  2. 父类的成员变量
  3. 子类的成员变量

传参方式 

  • 值传递  :传递的变量本身的值。一般程序中的值传递都是基本数据类型,如int、char等等

                在被调函数中只改变形参的值,而不会影响主调函数中实参的值

  • 引用传递 :传递的变量是在内存中的地址,在程序中常用的是数组、类和接口

               传递的是形参的地址,在被调函数中,对于形参的操作就是相当于操作实参本身

 New和malloc的区别

 new  / deletemalloc  /  free
属性运算符库函数
参数

无需指定内存大小

传入申请内存的大小
返回类型对象类型void*
分配失败抛出bac_alloc异常返回NULL
动作new申请内存空间后,会调用构造函数,底层是用malloc只申请内存
重载可以重载无法重载
内存区域自由存储区,抽象的概念堆区

指针和引用的区别

 
 指针引用
根本一个变量,变量存储的是另一个变量的地址一个别名,还是变量本身,操作引用就是操作变量本身
const可以有const指针  没有const引用,只有常量引用 int const &a
级数可以有多级指针没有多级引用
指针的值可以为空,赋值之后指针的值可以改变引用的值不能为空,定义时必须进行初始化,赋值之后不能改变
sizeof指针大小对象类型大小
运算含义++指针,所代表指针本身内存地址改变++引用,所代表变量本身改变

堆区和栈区的区别

 栈区堆区
管理方式由编译器自动管理由程序员管理
空间大小1M,有限x86 4G 
生长方向从高到低从低到高
分配方式静态、动态(alloca,且无需手动释放)动态
分配效率效率高,有专门的寄存器和指令效率低,需要按照一i的那个算法分配

 

空类

空类可以进行实例,大小为1,每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节。

这样空类在实例化后在内存得到了独一无二的地址,所以空类所占的内存大小是1个字节。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值