【C++】深入C++内存管理与多态:引用与指针、函数重载、新旧内存操作的全面解析

2024-09-04 08:46:46 浏览数 (3)

这里写目录标题
  • 引用和指针的区别
  • 函数重载
  • 解释一下什么是多态?
  • new,delete
  • free和delete的区别
  • new和delete能不能一起混用?
  • new的四大种

引用和指针的区别

代码语言:javascript复制
int a = 10;
int *p = &a;
int  &b = a;

*p = 20;
cout<<a <<" "<<*p<<" ”<< b<<endl; //20 20 20 
b = 30;
cout<<a <<" "<<*p<<" ”<< b<<endl; //30 30 30

int &c = 20;//错误,底层汇编指令无法生成
  • 引用是一种更安全的指针 引用是必须初始化的,指针可以不初始化 引用只有一级引用,没有多级引用 指针可以有一级指针,也可以有多级指针

引用和指针在底层汇编指令是一样的,通过引用变量修改所引用内存的值,和通过指针解引用修改指针指向的内存的值,其底层指令也是一样的。

  1. 左值引用·.右值引用 左值: 有内存,有名字,只可以修改 右值:没内存,没名字
代码语言:javascript复制
int &&a = 20;
//专门用来引用右值类型,指令上,可以自动产生临时量 然后直接引用临时量 a = 30;

const int &b = 20;
//区别:a可以再赋值修改,b不可以

int &&c = a;
//一个右值引用变量本身是一个左值,只能用左值引用来引用它
//不能用一个右值引用变量来引用一个左值

函数重载

  1. C 为什么支持函数重载,c语言不支持 C 代码产生函数符号的时候,函数名 参数列表类型组成 C代码产生函数符号的时候,函数名来决定。
  2. 函数重载需要注意什么? C 与C语言之间如何互相调用

函数重载:一组函数,其函数名相同,参数列表的个数或者类型不同,那么这一组函数可就称为函数重载。(前提函数一定处在同一作用域下) 返回值类型与函数是不是重载不会影响。

解释一下什么是多态?

  • 静态多态(编译时期)-》函数重载
  • 动态多态(运行时期)
  1. 当C 调用c代码时,无法直接调用
  • 解决办法:把C函数的声明扩在extern “c”{ int sum();}
  1. 当C调用c 代码时,无法直接调用
  • 解决办法:把C 函数的源码扩在extern “c”{ int sum(){ int sad;}}

下面代码无论在C 编译器还是C编译器下都可以直接运行

代码语言:javascript复制
#ifdef __cplusplus
extern "c"{
#endif
 int sum(int a, int b)
 {
 return a b;
 }
 #ifdef __cplusplus
 }
 #endif
  1. 重载关系:一组函数要重载,必须处在同一个作用域当中,而且函数名字相同,参数列表不同
  2. 隐藏(作用域的隐藏)关系:在继承结构当中,派生类的同名成员,把基类同名成员给隐藏调用了

new,delete

new和malloc的区别是什么?

malloc和free称作C的库函数。 new和delete称作运算符

new不仅可以做内存开辟,还可以做内存初始化操作

malloc开辟内存失败,是通过返回值和nullptr做比较的 new开辟内存失败,是通过抛出bad_alloc类型的异常 来判断的

malloc按字节开辟内存的 new开辟内存时需要指定类型 所以malloc开辟内存返回的都是void * ,

malloc只负责·开辟内存空间,new不仅仅有malloc的功能还可以进行数据的初始化。(对于数组只能初始化为0)

free和delete的区别

delete (int*)p; //先调用析构函数,再进行free(p);

new == operator new delete =.= operator delete

new和delete能不能一起混用?

C 为什么会区分单个元素和·数组的·内存分配和·释放 new delete new[] delete[]

对于普通编译器内置类型 new/delet[] new[]/delete 可以混用,但是不推荐 对于自定义类类型,有析构函数,为了调用正确的析构函数,那么开辟对象数组的时候会多开辟4个字节,用于记录对象的个数。 也正是这4个字节,在delete[] 时会自动把地址的起始位置-4,但是对于delete不会,它单单只会释放当前位置的内存,从而引发内存泄漏。所有报错异常终止。

new的四大种

代码语言:javascript复制
抛出异常的new
int *p1 = new int(20);
不抛出异常的new
int *p2 = new (nothrow) int;
在堆上创建的常量new
const int *p3 = new const int(40);
定位new
int data = 10;
int *p4 = new (&data) int(50);
cout<<"data = "<< data << endl;//data =50

0 人点赞