zoukankan      html  css  js  c++  java
  • this指针 new 和delete

    指针类型的函数:函数的返回值是指针。

    不要将非静态局部地址用作函数的返回值,离开函数后就失效了

    在子函数中定义局部变量后将其地址返回给函数就是非法地址

    在子函数中用new操作取得的内存地址返回给主函数合法有效,不会自动消失,必须用delete。

    函数指针的用途——函数回调:将函数指针用作参数传递给另一个函数,例子如下

    int compare (int a ,int b ,int (*fun)(int,int)) 

    {return fun(a,b);}

    int max(int a, int b)

    {return ((a>b)>?a:b);}

    int min(int a,int b)

    {return ((a>b)>?a:b);}

    函数指针充当不同的函数名,调用相应的函数功能

    -------------------------------------------------------------

    this指针:隐含于类的每个非静态成员函数中,参数列表为空,实际传了当前对象的地址给this,不然返回的时候不知道给谁

    -----------------------------------------------------------

    当不知道处理数据规模有多大,也不知道数组为多大合适,直到程序运行起来才确定,这时候就需要动态分配内存单元,动态分配的内存单元,来不及起变量名,没有数组名,只返回一个首地址。

    分配和释放动态数组:

    new    类型名T  [数组长度]  // 数组长度可以是任何整数类型表达式,在运行时计算

    delete  []   指针名 //删除的是指针所指对象,不是删除指针,指针还可以赋值 

    delete pi; //这是释放了pi所指的目标的内存空间,也就是撤销了目标,但指针pi并没有撤销,它依然存在,该指针所占内存空间并未释放

    int *pi=new int (0);  大致等价 int val=0; *pi=&val;  区别就是在堆中分配对象没有名字,不会自动初始化,必须用括号中的值初始化该对象

    delete是如何知道要为多少个对象调用析构函数的: 

    new在分配内存时,对于需要调用析构函数的类,会多分配对应类型的字节数,如:int就分配4个字节来保存对象的个数,所以在delete的时候括号中不用写明释放大小。

    char (*fp)[3]; //二维数组,这个fp是指向整个数组的指针,fp+1是越过整个行

    接受一个动态分配多维数组首地址的指针,要定义一个指向多维数组的指针,去掉第一维的下标个数,后面的都留着。

    --------------------------------------------------------

    智能指针:

    unique_ptr:不允许多个指针共享资源,可以用标准库中的move函数转移指针

    shared_ptr:多个指针共享资源

    weak_ptr:可复制shared_ptr,但其构造或释放对资源不产生影响

    -------------------------------------------------------

    当定义一个封装动态数组的类,把内存空间分配和释放都在类中定义,使用更安全方便,存在的问题,自己封装的动态数组,只能容纳一个数据类型

    解决办法:采用vector,能容纳任何类型的数组,只需要使用时告诉它类型即可,自动进行内存空间分配和删除,并进行下标越界检查

    vector是个模板,vector<double> 就生成一个double这么一个类,这个类专门用来存放double类型元素,在vector中已经重载了下标运算符。

    -------------------------------------------------------

    有的时候复制构造是不必要的,可以通过移动解决

    因此有了移动语义,将源对象资源的控制权全部交给目标对象

    针对:临时对象即将消亡,并且里面的资源仍旧需要

    实现方法:   用参数对应的指针对象来初始化当前对象的指针,然后把参数对象指针置为空指针,析构函数delete一个空指针不发生任何事情

    即将消亡的值和函数返回的临时变量是右值。

    -----------------------------------------------------

    使用动态分配内存的数组,需要自己定义一个类,并且要定义构造和析构函数,每个类只能存放特定一种类型

    用vector模板类,其中已经定义好了构造,析构函数,不用自己定义,而且只需要使用时先告诉它需要定义一个什么类对象<>传入即可,vector中可以存放任何类数据类型。

    -----------------------------------------------------

    new和delete是管理堆内存的

    new的过程:

    用关键字new在堆上动态创建一个对象,只不过返回指向首地址的指针,总共做了三件事:

    1,获得一块内存空间(大小由类型决定)

    2,调用构造函数——在创建简单类型变量时这步可省略

    3,返回正确的指针

    new失败时会调用分配内存失败处理程序

    delete是如何知道要为多少个对象调用析构函数的:new分配内存空间时,针对需要调用析构函数的类,多分配对应类型的字节数,如:int就分配4个字节来保存对象的个数,所以在delete的时候括号中不用写明释放大小。

    ---------------------------------------------------------

    new operator,就是平时用的new

    operator new:像加减乘除一样可以被重载,步骤:首先调用分配内存的代码,尝试得到一段堆上的空间,成功则返回,失败去调用new_handle重复前面的过程

    placement new: 定位构造,实现new的第二步,在取得一块可容纳指定类型对象的内存后,在这块内存上构造对象,使用时必须包含头文件new,并且可以在栈上构造,可以在堆或者栈上构造。

    -------------------------------------------------------

    new()分配这种类型的一个大小的内存空间,并用括号中的值来初始化这个变量

    new[] 分配这种类型的n个大小的内存空间,并用默认构造函数来初始化这些变量

    operator new:是个全局函数,写在一个文件中,当使用new关键字时,编译器会自动找到这个函数并调用这个函数

    全局主要是因为每个类还可以重载自己的operator new() 函数

    malloc用在内置数据类型或结构时,能满足需求,用在类类型时不能

    new即分配堆内存,又自动调用类的构造函数来创建对象

    new(申请内存时还调用构造函数)和delete(释放内存前,会调用析构函数),是运算符,对应C中的malloc(只会申请内存)和free(只会释放内存),是函数,

    每个new获得对象后,必须用delete释放

    C++98中,new创建的对象数组不能被显式初始化,数组所有元素被确省初始化,数组元素类型必须有构造函数

    C++11中允许显式初始化: int *p_int=new int[3] {1,2,3}

     引自:https://blog.csdn.net/hihozoo/article/details/51441521

  • 相关阅读:
    mysql复习相关
    OpenStack三种类型的NAT转换
    openstack资料相关
    [转]Web 调试工具之 Advanced REST client
    [转]Aspose.Words.dll 将 Word 转换成 html
    [Android] 开发第十天
    [win10]遇坑指南
    [转]Explorer.exe的命令行参数
    [Android] 开发第九天
    [Android] 开发第八天
  • 原文地址:https://www.cnblogs.com/ymd12103410/p/9565469.html
Copyright © 2011-2022 走看看