【转】c++ new操作符的重载
基本概念:
1. 操作符重载:C++支持对某个操作符赋予不同的语义
2. new操作符:申请内存,调用构造函数
关于c++ new操作符的重载
你知道c++ 的new 操作符和operator new 的区别么?也许你还会问,他们有区别吗?
当你写下面这样的代码时,
string *pa = new string("memory managerment");
你使用的是new 操作符,这个操作符和sizeof 一样,是c++ 语言级别支持的。你不能改变它的语义,它做的事情总是不变的:分配足够的内存以容纳对象,然后调用构造函数初始化上一步所分配的内存。New 操作符总是做这两件事情,你不能改变它的行为。
你所能改变的只是第一步的行为,如何为对象分配RAW 内存。operator new 函数用来为对象分配原始内存。New操作符的第一步调用的就是operator new 。你可以重载这个函数。它的原型如下:
Void* operator new(size_t size);
函数的返回值是void*, 因为这个函数返回的是指针。这个指针指向原生的,为初始化的内存。其语义就像malloc 。实际上它内部调用的就是malloc 。参数size 指定待分配的内存大小。你可以在重载的时候加上额外的参数,但是第一个参数类型必须是size_t.
绝大多数情况下,你不需要调用operator new, 万一你需要调用它,调用的格式是这样的:
Void* rawmemory = operator new(sizeof(string));
函数operator new 将返回一个指针,指向一块足够容纳一个string 对象的内存。
就像malloc 一样,operator new 的唯一的职责就是分配内存,它对构造函数一无所知。把operator new 返回的未初始化的指针构造成一个对象是new 操作符的工作。当你的编译器遇到以下的代码时:
string *pa = new string("memory managerment");
它生成的伪代码类以如下:
void* memory = operator new(sizeof(string));
call string::string("memory managerment") on memory ;
string* Pa = static_cast<string*>(memory);
第二布包含了构造函数的调用。这是你的编译器调用的。那么你不紧会问,程序员可以手动调用构造函数吗?答案是否定的。但是编译器同时给你提供了另外一个折中,是你可以达到这个目的。
需要说明的是,在一个已存在的对象上调用构造函数是没有任何意义的。因为构造函数用来初始化对象。但是有时候有一些内存已经被分配但是尚未初始化,你需要在这些内存中构造一个对象。你可以使用operator new 函数的一个特殊版本。一个术语叫 placement new 的函数来做这件事情。
回到前面那个字符串的例子,我们可以这样使用placement new :
Void* memory = operator new(sizeof(string));
String* pa = new (memory) string("memory managerment");
以上两句就相当于new 操作符所做的事情了。
这就是operator new 和placement new 的全部秘密。一般的来说,你不需要重载和显式调用这两个函数。
原文地址:http://blog.csdn.net/bichenggui/article/details/4823978#comments
【转】c++ new操作符的重载的更多相关文章
- C++ 重载操作符- 02 重载输入输出操作符
重载输入输出操作符 本篇博客主要介绍两个操作符重载.一个是 <<(输出操作符).一个是 >> (输入操作符) 现在就使用实例来学习:如何重载输入和输出操作符. #include ...
- C++中前置操作符和后置操作符的重载
1,C 语言中讨论了原生含义,C++ 中有必要考虑前置.后置操作符能够重载,有何问题: 2,值得思考的问题: 1,下面的代码有没有区别?为什么? 1,i++ // i 的值作为返回值,i 自增 1: ...
- C#操作符的重载
操作符也是可以重载的,先总结一下操作符的性质: 如我们所知,操作符在不同的情况下有不同的语义,具体取决于它所操作的类型.例如,操作符“+”在操作数值类型的时候意味着“加”,在操作字符串时意味着“连接” ...
- C++ 指针悬挂和赋值操作符的重载,拷贝构造函数实现
指针悬挂: 问题:使用new申请的内存内存空间无法访问,也无法释放. 原因:直接对指向new申请的存储空间的指针变量进行赋值修改 后果:失去了原来的地址,原来的空间无法访问也无法释放,造成内存泄漏 还 ...
- 第34课.数组操作符的重载("[]"重载)
1.问题:string类对象还具备c方式字符串的灵活性吗?还能直接访问单个字符吗? 答案:可以按照c字符串的方式使用string对象 string s = "a1b2c3d4e"; ...
- C++中 关于操作符的重载
C++实现了类的定义,也可以对类之间的操作符进行定义,又叫重载. 例如同类之间的 加.减法,赋值等等操作. 具体看http://blog.csdn.net/zhy_cheng/article/deta ...
- C++中函数调用操作符的重载
1,本博文讲述函数对象问题: 2,客户需求: 1,编写一个函数: 1,函数可以获得斐波那契数列每项的值: 2,每调用一次返回一个值: 3,函数可根据需要重复使用: 4,代码示例: ; i<; i ...
- 第37课 智能指针分析(指针特征操作符( -> 、 *)重载)
1. 永恒的话题:内存泄漏 (1)动态申请堆空间,用完后不归还 (2)C++语言中没有垃圾回收的机制 (3)指针无法控制所指堆空间的生命周期------------指针是变量,可以指向内存堆空间,但是 ...
- day_其他操作符的重载
#include <iostream> #include <stdlib.h> using namespace std; class A{ public: A(void) { ...
随机推荐
- JavaEE开发之Spring中的事件发送与监听以及使用@Profile进行环境切换
本篇博客我们就来聊一下Spring框架中的观察者模式的应用,即事件的发送与监听机制.之前我们已经剖析过观察者模式的具体实现,以及使用Swift3.0自定义过通知机制.所以本篇博客对于事件发送与监听的底 ...
- 用代码控制退出APP
+ (void)exitApplication { AppDelegate *app = [UIApplication sharedApplication].delegate; UIWindow *w ...
- JAVA-实例方法被覆盖,静态方法被隐藏Explain
被覆盖比较好理解,类似于多态的实现. 被隐藏是指静态方法的访问是根据当前对象的表面类型来决定的,比如 Supers = new Sub(); s.greeting()访问的是Super的静态方法,如果 ...
- ajax VS websocket
一. ajax VS websocket总结 http://blog.csdn.net/qiuhuanmin/article/details/50719114 二.用Websocket代替Ajax来开 ...
- winform 自定义分页控件 及DataGridview数据绑定
分页效果如上图所示,用到的控件均为基本控件 ,其方法如下 右击项目-添加-新建项 选择用户控件 然后在用户控件中拖入所需要的Label,Button,Text 用户控件全部代码: using Syst ...
- python webdriver安装
前言 本次就python webdriver的安装和驱动不同浏览器的配置进行分享,以解决大家在入门过程中的一些基本的环境问题. python安装 目前python有2.x和3.x版本,笔者在这里推荐2 ...
- scss的初级学习随笔小计
$white: #fff;$three: #333;$six: #666;$nine: #999;$red: #fff;$orange: #f63;$yellow: #fc0;$opcity: rgb ...
- Webdriver API之元素定位
Webdriver提供了8种元素定位方法:id.name.class name.tag name.link text.partial link text.xpath.css selector 一.以上 ...
- WebForm捆绑压缩js和css(WebForm Bundling and Minification)
.net framework 4以上,可以使用Microsoft.AspNet.Web.Optimization 新建4.0项目 Nuget搜索optimization,安装第一个包 加入Bundle ...
- spring boot summer快速开发框架之《一、数据库操作》
快速开发演示: 目录结构: 本例采用的mysql自带的sakila示例库,脚本DumpAddress.sql. 步骤:1. 修改application.properties中数据库连接2. 在App. ...