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
this指针 new 和delete的更多相关文章
- c/c++ 复习基础要点01-const指针、指针函数 函数指针、new/delete与malloc/free区别与联系
1. 引用本身是有指针实现的:引用为只读指针 例子: int d=123; int& e=d; //引用 int * const e=d; //只读指针,e指向d,不可修改e指 ...
- [C++ Primer Plus] 第4章、复合类型(一)程序清单——指针new和delete
程序清单4.1 #include<iostream> using namespace std; void main(){ ]; yams[]=; yams[]=; yams[]=; ]={ ...
- 转载:指针delete后要设置为NULL
本文来自:http://rpy000.blog.163.com/blog/static/196109536201292615547939/ 众所周知,最开始我们用new来创建一个指针,那么等我们用完它 ...
- delete指针以后应赋值为NULL——QT deletelater指针以后也同样要马上赋值为NULL
delete p后,只是释放了指针指向的内存空间.p并不会自动被置为NULL,而且指针还在,同时还指向了之前的地址 delete NULL编译器不会报错(因为delete空指针是合法的) 例: 对一个 ...
- c++ 用new后delete,而继续输出指针后果 new/new[]/delete/delete[]区别
#include<iostream> #include<cstring> #include <string.h> int main(){ ]; ;i<;i++ ...
- C++指针delete后还要置为null
非常好的一篇说明: 转载:https://blog.csdn.net/qq_36570733/article/details/80043321 众所周知,最开始我们用new来创建一个指针,那么等我们用 ...
- 写了placement new就要写placement delete
"placement new"通常是专指指定了位置的new(std::size_t size, void *mem),用于vector申请capacity剩余的可用内存. 但广义的 ...
- iOS开发_内存泄漏、内存溢出和野指针之间的区别
今天,在工作群中,被问到了内存泄漏和野指针指向的区别,自己答的不是很好,特意回来查了资料,在博文中总结一下经验,欢迎指正. 内存泄漏:是指在堆区,alloc 或new 创建了一个对象,但是并没有放到自 ...
- C++提前delete
////////////////////////////////////// ///类析构以后,成员变量内存空间释放, ///函数 和 变量 还是可以引用的 ///////////////////// ...
随机推荐
- 远程批量查看windosws操作系统3389端口的开放情况
本文只提供思想.具体可以根椐情况拓展. 前提是需要配置远程主机的SNMP协议.主要是共同体哟. 脚本使用: 1.拷贝check_tcp到脚本执行的主机中或在此主机中安装nagios; 2.保持list ...
- javascript:getElementsByName td name
问题: 今天写动态生成HTML表格的时候需要用到统计td内的数据,在生成的时候设置了td的name属性,但是document.getElementsByName("tdname&quo ...
- centos 安装mysql数据库
在CentOS中默认安装有MariaDB,这个是MySQL的分支,但为了需要,还是要在系统中安装MySQL,而且安装完成之后可以直接覆盖掉MariaDB. 1 下载并安装MySQL官方的 Yum Re ...
- hdu3826-Squarefree number-(欧拉筛+唯一分解定理)
Squarefree number Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- laravel 命令行创建controller 创建数据库表迁移 创建module
1.php artisan 查看命令列表 2.php artisan make:controller ArticleController 命令 创建控制器 3.创建数据库迁移表 创建文章表 php a ...
- linux配置虚拟主机
linux 下怎么配置虚拟主机 linux 下怎么配置虚拟主机,在网上找到N个资料都是高手们随便说几句,都没怎么说清楚.问题: 我把域名(bs.jxiop.com)指向了 68.10.140.10 ...
- 常见三种字符编码的区别:ASCII、Unicode、UTF-8
什么是字符编码? 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255( ...
- MySQL 5.7 使用原生JSON类型
首先回顾一下JSON的语法规则: 数据在键值对中, 数据由逗号分隔, 花括号保存对象, 方括号保存数组. 按照最简单的形式,可以用下面的JSON表示: {"NAME": " ...
- cdh 安装系列2--cdh manager product 安装
前期准备工作: 准备三台centos7 地址分别为 192.168.20.163:192.168.20.162:192.168.20.161 用163这台机器链接外网,并安装manager以及mana ...
- python生成Excel图表(通过xlsxwriter)
前面介绍了pandas的简单用法,pandas的数据可以通过matlab第三方包将数据生成报表,但是我想将报表生成在Excel中,这时候就可以借助xlsxwriter第三方包来生成图标 缺点:xl ...