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;}

new/delete工作机制:
使用new表达式时发生的三个步骤:
1、调用名为operator new的标准库函数,分配足够大的原始的未类型化的内存,以保存指定类型的一个对象
2、运行该类型的一个构造函数去初始化对象
3、返回指向新分配并构造的构造函数对象的指针
使用delete表达式时,发生的步骤:
1、调用对象的析构函数
2、 调用名为operator delete的标准库函数释放该对象所用的内存
Student * pstu = new Student;
                new表达式:
                        a. opeartor new库函数 --> 专门用来开辟空间
                        b. 调用构造函数 --> 进行初始化
                        c. 返回所创建对象的首地址
                delete表达式:
                        a. 调用析构函数
                        b. 调用operator delete库函数 --> 释放申请的空间

operator new/delete
operator new 和operator delete函数有两个重载版本
void * operator new (size_t);
void * operator new[](size_t);
    void operator delete(void *);
    void operator delete[](void *);

只能生成栈对象
 不能通过new表达式来生成对象
1、将构造函数放入private区域
2、operator new函数 放入到private区域
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;
}
只能生成堆对象
在创建栈对象时,不能调用构造函数或者析构函数
1、将构造函数放到private区域      //不可以

2、将析构函数放到private区域     //对于堆对象而言,执行 delete 表达式不能调用析构函数,表一不通过;public 声明 destory() 函数来进行资源释放 
//只创建堆对象
//将析构函数放到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;
}
delete 和 delete[] 区别

 ///
/// @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工作机制的更多相关文章

  1. malloc 函数工作机制(转)

    malloc()工作机制 malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表.调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块.然后,将 ...

  2. BrnShop开源网上商城第三讲:插件的工作机制

    这几天BrnShop的开发工作比较多,所以这一篇文章来的晚了一些,还请大家见谅呀!还有通知大家一下BrnShop1.0.312版本已经发布,此版本添加了报表统计等新功能,需要源码的园友可以点此下载.好 ...

  3. 2014年2月5日 Oracle ORACLE的工作机制[转]

      网上看到一篇描写ORACLE工作机制的文章,觉得很不错!特摘录了下来.   ORACLE的工作机制-1 (by xyf_tck) 我们从一个用户请求开始讲,ORACLE的简要的工作机制是怎样的,首 ...

  4. OpenStack云平台的网络模式及其工作机制

    网络,是OpenStack的部署中最容易出问题的,也是其结构中难以理清的部分.经常收到关于OneStack部署网络方面问题和OpenStack网络结构问题的邮件.下面根据自己的理解,谈一谈OpenSt ...

  5. rsync工作机制(翻译)

    本篇为rsync官方推荐文章How Rsync Works的翻译,主要内容是Rsync术语说明和简单版的rsync工作原理.本篇没有通篇都进行翻译,前言直接跳过了,但为了文章的完整性,前言部分的原文还 ...

  6. OpenStack云平台网络模式及其工作机制

    转自:http://openstack.csdn.net/content.html?arcid=2808381 OpenStack云平台网络模式及其工作机制 网络,是OpenStack的部署中最容易出 ...

  7. tomcat中Servlet的工作机制

    在研究Servlet在tomcat中的工作机制前必须先看看Servlet规范的一些重要的相关规定,规范提供了一个Servlet接口,接口中包含的重要方法是init.service.destroy等方法 ...

  8. rsync(五)工作机制

    当我们讨论rsync时,我们使用了一些特殊的术语来代表不同的进程以及它们在任务执行过程中所扮演的角色.人类为了更方便.更准确地交流,使用同一种语言是非常重要的:同样地,在特定的上下文环境中,使用固定的 ...

  9. 大数据学习笔记——Spark工作机制以及API详解

    Spark工作机制以及API详解 本篇文章将会承接上篇关于如何部署Spark分布式集群的博客,会先对RDD编程中常见的API进行一个整理,接着再结合源代码以及注释详细地解读spark的作业提交流程,调 ...

随机推荐

  1. NodeJS NPM HTTPS

    npm config set registry http://registry.npmjs.org/

  2. 利用JS代码快速获得知网论文作为参考文献的引用文本

    写论文的时候,发现知网虽然提供了生成参考文献引用标注的功能,但是效率仍然不太高.我就忙里偷闲写了一段简单的脚本,能无延迟地生成这段引用文本.目前支持期刊论文和硕士论文. 代码: (function() ...

  3. eclipse中Web Deployment Assembly与build path作用

    java Build path是编译路径设置,主要用来设置源代码的编译路径默认是default output folder Web Deployment Assembly是eclipse中的发布路径设 ...

  4. oracle中add_months函数的用法

    如果需要取上一个月的数据,并且每天都要进行此操作,每次都需要改时间,的确非常的麻烦,所以想到了oracle add_months函数这个函数 oracle add_months函数: oracle a ...

  5. [原创]css中a标签去掉锚点文本下划线

    我对博客的认识是:记录问题,解决问题,分享知识.如果有轮子,我不需要造轮子. 1.问题解决方式: 设置属性:text-decoration:none; 2.更多属性参数参考 text-decorati ...

  6. Spark高级数据分析· 6LSA

    潜在语义分析 wget http://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles-multistream.xml.bz ...

  7. M4中遇到的问题

    MDK5的安装以及破解 这里遇到了一个问题,PDF上并没有扯个界面我就先截了个图然后点安装,后来看来这其中并没有什么问题 在这里就会出现卡死的情况,也就是说并不能从这个界面上下载两个相应的安装包 在M ...

  8. linux及安全第三周总结——20135227黄晓妍

    总结部分: Linux内核源代码: Arch 支持不同cpu的源代码:主要关注x86 Init   内核启动的相关代码:主要关注main.c,整个Linux内核启动代码start_kernel函数 K ...

  9. Java -D命令对应的代码中获取-D后面的参数 和 多个参数时-D命令的使用

    1. Java代码: public class TestDPara { public static void main(String[] args) { String flag = System.ge ...

  10. Mybatis中使用自定义的类型处理器处理枚举enum类型

    知识点:在使用Mybatis的框架中,使用自定义的类型处理器处理枚举enum类型 应用:利用枚举类,处理字段有限,可以用状态码,代替的字段,本实例,给员工状态字段设置了一个枚举类 状态码,直接赋值给对 ...