new/delete工作机制
body, table{font-family: 微软雅黑; font-size: 10pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}
|
Student * pstu = new Student;
new表达式:
a. opeartor new库函数 --> 专门用来开辟空间
b. 调用构造函数 --> 进行初始化
c. 返回所创建对象的首地址
delete表达式:
a. 调用析构函数
b. 调用operator delete库函数 --> 释放申请的空间
|
|
void * operator new (size_t);
void * operator new[](size_t);
|
void operator delete(void *);
void operator delete[](void *);
|
|
private:
void * operator new(size_t count);
void operator delete(void * p);
//重写new/delete,可以不去实现,类外就不能调用new来创建对象
|
|
//只生产栈对象,不生成堆对象
//1.将构造函数放入private区域; new生成堆对象的第二步就是要调用构造函数,设置为私有,new就不能成功
//2.operator new函数 放入到private区域
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
class Student
{
private:
int _id;
char *_name;
void * operator new(size_t count){} //只是为了不生成堆对象,没必要重写
void operator delete(void *p){}
public:
Student(int id,const char *name):_id(id)
{
cout<<"Student()"<<endl;
_name = new char[strlen(name)+1];
strcpy(_name,name);
}
~Student()
{
cout<<"~Student()"<<endl;
delete []_name;
_name = NULL;
}
void print()const
{
cout<<"id:"<<_id<<endl;
cout<<"name:"<<_name<<endl;
}
};
|
int main(void)
{
//Student *stu = new Student(110,"meihao"); //new 创建Student类对象时才会调用Student类内部重写的new、delete表达式
Student stu1(110,"meihao");
stu1.print();
return 0;
}
|
|
//只创建堆对象
//将析构函数放到private区域
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
class Student
{
private:
int _id;
char *_name;
public:
Student(int id,const char *name):_id(id)
{
cout<<"Student()"<<endl;
_name = new char[strlen(name)+1];
strcpy(_name,name);
}
private:
~Student()
{
cout<<"~Student()"<<endl;
delete []_name;
_name = NULL;
}
public:
void destory()
{
cout<<"destory()"<<endl;
delete this; //只能创建堆对象,对象调用会传递this指针
//this->~Student(); //这个也可以
}
void print()const
{
cout<<"id:"<<_id<<endl;
cout<<"name:"<<_name<<endl;
}
};
|
int main(void)
{
Student *stu1 = new Student(110,"meihao");
stu1->print();
//delete stu1; //不能调析构函数,无法释放
stu1->destory();
//Student stu1(110,"meihao"); //析构函数是私有,可以创建对象但是不能释放,编译不通过
return 0;
}
|
|
///
/// @file testDelete[].cpp
/// @author meihao1203(meihao19931203@outlook.com)
/// @date 2018-08-11 19:47:35
///
#include<iostream>
using namespace std;
class A
{
public:
A():_a(new char[1])
{
++cnt;
cout<<"A()"<<endl;
}
~A()
{
delete []_a;
cout<<"~A()"<<cnt<<endl;
}
private:
static int cnt;
char* _a;
};
int A::cnt = 0;
int main()
{
int* arr = new int[2];
int* arr2 = new int[2];
delete arr;
delete []arr2; //内置类型都能正常释放
cout<<"------"<<endl;
A* arr3 = new A[2];
delete []arr3;
cout<<"------"<<endl;
A* arr4 = new A[2]; //只会调动一次析构函数
delete arr4;
return 0;
}
------
A()
A()
~A()2
~A()1
------
A()
A()
~A()2
//core dump
|
使用valgrind查看内存泄露:
内置类型,内存大小已经确定,系统可以记忆并且进行管理,在析构时不会调用析构函数。
类类型,delete ptr只用来释放ptr指向的内存。
delete []ptr用来指向ptr指向的内存,并逐一调用数组中每个对象的析构函数
|
new/delete工作机制的更多相关文章
- malloc 函数工作机制(转)
malloc()工作机制 malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表.调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块.然后,将 ...
- BrnShop开源网上商城第三讲:插件的工作机制
这几天BrnShop的开发工作比较多,所以这一篇文章来的晚了一些,还请大家见谅呀!还有通知大家一下BrnShop1.0.312版本已经发布,此版本添加了报表统计等新功能,需要源码的园友可以点此下载.好 ...
- 2014年2月5日 Oracle ORACLE的工作机制[转]
网上看到一篇描写ORACLE工作机制的文章,觉得很不错!特摘录了下来. ORACLE的工作机制-1 (by xyf_tck) 我们从一个用户请求开始讲,ORACLE的简要的工作机制是怎样的,首 ...
- OpenStack云平台的网络模式及其工作机制
网络,是OpenStack的部署中最容易出问题的,也是其结构中难以理清的部分.经常收到关于OneStack部署网络方面问题和OpenStack网络结构问题的邮件.下面根据自己的理解,谈一谈OpenSt ...
- rsync工作机制(翻译)
本篇为rsync官方推荐文章How Rsync Works的翻译,主要内容是Rsync术语说明和简单版的rsync工作原理.本篇没有通篇都进行翻译,前言直接跳过了,但为了文章的完整性,前言部分的原文还 ...
- OpenStack云平台网络模式及其工作机制
转自:http://openstack.csdn.net/content.html?arcid=2808381 OpenStack云平台网络模式及其工作机制 网络,是OpenStack的部署中最容易出 ...
- tomcat中Servlet的工作机制
在研究Servlet在tomcat中的工作机制前必须先看看Servlet规范的一些重要的相关规定,规范提供了一个Servlet接口,接口中包含的重要方法是init.service.destroy等方法 ...
- rsync(五)工作机制
当我们讨论rsync时,我们使用了一些特殊的术语来代表不同的进程以及它们在任务执行过程中所扮演的角色.人类为了更方便.更准确地交流,使用同一种语言是非常重要的:同样地,在特定的上下文环境中,使用固定的 ...
- 大数据学习笔记——Spark工作机制以及API详解
Spark工作机制以及API详解 本篇文章将会承接上篇关于如何部署Spark分布式集群的博客,会先对RDD编程中常见的API进行一个整理,接着再结合源代码以及注释详细地解读spark的作业提交流程,调 ...
随机推荐
- redis 简单命令操作
一.概述: 在该系列的前几篇博客中,主要讲述的是与Redis数据类型相关的命令,如String.List.Set.Hashes和Sorted-Set.这些命令都具有一个共同点,即所有的操作都是针对与K ...
- oracle中修改表已有数据的某一列的字段类型的方法,数据备份
1.在开发过程中经常会遇到表中的某一个字段数据类型不对,比如说需要保存的数据带小数,但是在最初设计的时候是给的number(10)类型,开始保存是整数的时候满足要求,后来在保存小数的时候 会发现自动四 ...
- git命令学习汇总
GIT 版本控制常用命令汇总 git version 查看当前git版本信息 git help 获取全部命令帮助信息 git help <command> 获取指定命令帮助信息 git c ...
- Java-性能调优实战(jps、jstack)
找最耗CPU的线程 1. 找出java进程 [ ~]# jps 9939 Resin 9874 WatchdogManager 9926 Jps 2. 找java进程下所有的线程 [ ~]# top ...
- 20145328 《Java程序设计》实验三实验报告
20145328 <Java程序设计>实验三实验报告 实验名称 Java敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验步骤 (一)敏捷开发与XP 敏捷开发是一种以人为 ...
- 20135302魏静静——linux课程第七周实验及总结
linux课程第七周实验及总结 实验及学习总结 1. 编译链接的过程和ELF可执行文件格式(以hello为例) GNU编译系统编译源码: 首先,运行C预处理器(cpp),将.c文件翻译成.i文件——g ...
- shell编程学习笔记之sed编辑器
在shell编程中,大多数处理的都是文本文件.对文本文件进行处理除了使用交互式文本编辑器(vi[m],gedit......)也可以使用另外一类:流编辑器. 流编辑器:使用预定义的编辑规则来对文本进行 ...
- linux如何以十六进制格式来查看任意文件
答:vim+xxd 使用方法如下: 1.vim -b file.txt 2.在vim的命令行模式下对文件进行16进制转换 输入:%!xxd 3.在vim的命令行模式下回到正常格式 输入:%!xxd - ...
- 【转载】JExcelApi(JXL)学习笔记
在公司的项目中,有excel生成.导出的需求,因此学习了用JXL读写excel,做个简单的笔记,以供参考. 实现用java操作excel的工具,一般用的有两个:一个是JXL,另一个是apac ...
- Java ArrayList在foreach中remove的问题分析
目录 iterator itr.hasNext 和 itr.next 实现 倒数第二个元素的特殊 如何避坑 都说ArrayList在用foreach循环的时候,不能add元素,也不能remove元素, ...