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. 在vi中打开多个文件,复制一个文件中多行到另一个文件中

    :set number 查看行号1.vi a.txt b.txt或者vi *.txt 2.文件间切换 :n切换到下一个文件,:wn保存再切换 :N到上一个文件,:wN保存再切换 :.=看当前行 3.比 ...

  2. MVC通过服务端对数据进行验证(和AJAX验证一样)

    在实体类中 添加 Remote属性,指定用某个View下的某个方法进行验证,如下面表示用User控制器中的UserExiting方法验证 public    class   User { [Remot ...

  3. MVC中关于 使用后台代码 检查 用户名是否已经被清册

    在 注册页面  NewUser 的 Controller中写以下代码 public  ActionResult GetUserIndataByUserName() { string UserName= ...

  4. Spring七大框架

    Spring Core:最基础部分,提供IOC和依赖注入.基础概念是BeanFactory,提供对Factory模式的经典实现,这样来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关 ...

  5. sqlx基础语法与应用

    基础: ``` 引用:_ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ``` 初始化 ...

  6. Helloworld.JaVa 第一次编程

    package Jc; class Jc1st { public static void main(String[] args) { System.out.println("Hello Wo ...

  7. JVM 内存调优 与 实际案例

    堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...

  8. 解题报告:hdu1284 钱币兑换问题

    2017-09-03 19:03:06 writer:pprp 状态定义: dp[i][j] = x 代表的是 用前i 中硬币构造 j 美分的方法数目: 初始化: dp[0][0] = 1 状态转移: ...

  9. HMM代码实践

    本文主要转载于:http://www.52nlp.cn/hmm-learn-best-practices-eight-summary 这个文章是边看边实践加上自己的一些想法生成的初稿..... 状态转 ...

  10. winform中的ListBox和ComboBox绑定数据

    将集合数据绑定到ListBox和ComboBox控件,界面上显示某个属性的内容 //... //自定义了Person类(有Name,Age,Heigth等属性) List<Person> ...