c++ new操作符的重载

感谢原文作者,为我揭开C++又一个盲点。

原文地址:http://blog.csdn.net/bichenggui/article/details/4823978

关于c++ new操作符的重载

你知道c++ 的new操作符和operator new的区别么?也许你还会问,他们有区别吗?

 

当你写下面这样的代码时,

string *pa = new string("memory managerment");

你使用的是new操作符,这个操作符和sizeof一样,是c++语言级别支持的。你不能改变它的语义,它做的事情总是不变的:分配足够的内存以容纳对象,然后调用构造函数初始化上一步所分配的内存。New操作符总是做这两件事情,你不能改变它的行为。

 

你所能改变的只是第一步的行为,如何为对象分配RAW内存。operatornew函数用来为对象分配原始内存。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") onmemory;

string* Pa = static_cast<string*>(memory);

 

第二布包含了构造函数的调用。这是你的编译器调用的。那么你不紧会问,程序员可以手动调用构造函数吗?答案是否定的。但是编译器同时给你提供了另外一个折中,是你可以达到这个目的。

需要说明的是,在一个已存在的对象上调用构造函数是没有任何意义的。因为构造函数用来初始化对象。但是有时候有一些内存已经被分配但是尚未初始化,你需要在这些内存中构造一个对象。你可以使用operator new函数的一个特殊版本。一个术语叫 placement new的函数来做这件事情。

回到前面那个字符串的例子,我们可以这样使用placement new:

Void* memory = operator new(sizeof(string));

String* pa = new (memory) string("memorymanagerment");

 

以上两句就相当于new 操作符所做的事情了。

这就是operator new和placement new的全部秘密。一般的来说,你不需要重载和显式调用这两个函数。

时间: 2024-09-20 00:05:32

c++ new操作符的重载的相关文章

c语言-C语言:-&amp;amp;gt;操作符可以重载吗?他是单目操作符吗?

问题描述 C语言:->操作符可以重载吗?他是单目操作符吗? ->操作符可以重载吗?他是单目操作符吗? xxx operator->() { ..... } 解决方案 http://blog.chinaunix.net/uid-17019762-id-183397.html 解决方案二: 没注意你的标题,C语言哪来的符号载重? 解决方案三: 如果是C++语言,->可以重载: C没有重载的概念 解决方案四: C++中可以重载,C语言没有重载概念,具体如何重载参考这里:http://bl

C++之CNoTrackObject类和new delete操作符的重载实例_C 语言

本文实例讲述了C++中CNoTrackObject类和new delete操作符的重载,分享给大家供大家参考.具体如下: 头信息: 复制代码 代码如下: class CNoTrackObject{  public: //在此出过错,没有加public 默认为类的私有变量,MyThreadData继承这个类后也无法访问成员变量      void* operator new(size_t nSize);      void operator delete(void*);      virtual

C#锐利体验之第八讲 索引器与操作符重载

索引 索引器 索引器(Indexer)是C#引入的一个新型的类成员,它使得对象可以像数组那样被方便,直观的引用.索引器非常类似于我们前面讲到的属性,但索引器可以有参数列表,且只能作用在实例对象上,而不能在类上直接作用.下面是典型的索引器的设计,我们在这里忽略了具体的实现. class MyClass{    public object this [int index]    {        get        {            // 取数据        }        set  

C++的操作符重载概述

1.什么是操作符重载 可以使用分词将操作符重载理解为:操作符+重载. C++中的操作符很多,如+,-,*,\等等. C++中的重载也是C++中面向对象多态的体现. 简单说操作符重载: C++中有:int a=2+3; 那么a=5 操作符重载可以实现对自定义类型的操作: #include <iostream> using namespace std; class Point{ public: int x; int y; Point(int _x,int _y):x(_x),y(_y){ } Po

C#操作符重载

11.5.1 问题的提出 在面向对象的程序设计中,自己定义一个类,就等于创建了一个新类型.类的实例和变量一样,可以作为参数传递,也可以作为返回类型. 在第七章中,我们介绍了系统定义的许多操作符.比如对于两个整型变量,使用算术操作符可以简便地进行算术运算: class A { public int x; public int y; public int Plus{ return x+y; } } 再比如,我们希望将属于不同类的两个实例的数据内容相加: class B { public int x;

Way on c &amp;amp; c++ 小记 [七] – 重载操作符

重载操作符 作者:Jason Lee @http://blog.csdn.net/jasonblog 日期:2010-04-17   [1]重载操作符 重载操作符从大的方面来讲可以分为两类:最好或必须作为类的成员函数的,以及相反.而具体地讲,最好或必须作为类的成员函数的有赋值操作符( = ).下标操作符( [] ).调用操作符( () ).成员访问箭头操作符( ->,目前列出的操作符都必须为成员函数) .星号解引用操作符( * ).复合赋值操作符( +=等).自增.自减.其它的一些操作符,如算术

C++输入输出操作符重载的深入分析_C 语言

操作符的重载有一些规则: 1. 重载操作符必须具有一个类类型或枚举类型操作数.这条规则强制重载操作符不能重新定义用于内置类型对象的操作符的含义.如:int operator+(int, int), 不可以    2. 为类设计重载操作符的时候,必须选择是将操作符设置为类成员还是普通非成员函数.在某些情况下,程序没有选择,操作符必须是成员:在另外一些情况下,有些经验可以指导我们做出决定.下面是一些指导:a. 赋值(=),下标([]),调用(())和成员访问箭头(->)等操作符必须定义为成员,将这些

C++ new、delete(new[]、delete[])操作符重载需要注意的问题_C 语言

new.delete(new[].delete[])操作符的重载需要注意: 1.重载的 new.delete(或者 new[].delete[])操作符必须是类的静态成员函数(为什么必须是静态成员函数,这很好理解,因为 new 操作符被调用的时候,对象还未构建)或者是全局函数,函数的原型如下: 复制代码 代码如下: void* operator new(size_t size) throw(std::bad_alloc); // 这里的 size 为分配的内存的总大小 void* operato

C++中的操作符重载详细解析_C 语言

一.什么是操作符重载操作符重载可以分为两部分:"操作符"和"重载".说到重载想必都不陌生了吧,这是一种编译时多态,重载实际上可以分为函数重载和操作符重载.运算符重载和函数重载的不同之处在于操作符重载重载的一定是操作符.我们不妨先直观的看一下所谓的操作符重载: 复制代码 代码如下: #include <iostream> using namespace std; int main(){    int a = 2 , b = 3;    float c =