小结:c++中的new、operator new和placement new

c++中的new、operator new和placement new

一、new

  • new(也称作new operator),是new 操作符,不可重载
class T{...};
T *t = new T(initial_args_list); //此时的new ,是new 操作符

new操作 会执行以下三个步骤

  1. 调用类的(如果重载了的话)或者全局的operator new分配空间
  2. 用类型后面列的参数列表来调用构造函数,生成类对象
  3. 返回对应的指针

二、 operator new

  • operator new是 operator 函数,与operator +等函数类似,可以被重载,operator new一般在类中进行重载。在全局重载容易造成程序崩溃,因为全局的::operator new 负责整个程序运行期间的堆空间的分配,重载全局::operator new 须慎之又慎!

例:

class T{
    ...
    void* operator new(size_t){
    ... //自定义操作
      return ::operator new(size_t);
  }
};

三、placement new

  • 是重载operator new 的一个标准、全局的版本

  • 它不能够被自定义的版本代替,即不能重载。它的作用是在已分配的空间中构造对象。

  void *operator new( size_t, void * p ) throw() { return p; }

Placement new使用步骤

在很多情况下,placement new的使用方法和其他普通的new有所不同。这里提供了它的使用步骤。

  • 缓存提前分配
char*buf = (::operator new((size_t)(sizeof(T))));
  • 对象的分配,在已分配的缓存中调用构造函数,生成对象
T *t = new(buf)T;
  • 使用对象,用-> 访问对象的成员
t->men_func();
  • 调用外在的析构函数
t->~T();
  • 释放资源
delete [] buf;

使用例子:

#include <stdio.h>
#include <iostream>
#include <string>
#include <malloc.h>
using namespace std;


class testNew{
public:
    testNew(){ cout << "执行了testNew::testNew() 构造函数" << endl; }
    ~testNew(){ cout << "执行了testNew::~testNew() 析构函数" << endl; }

    void* operator new(size_t size, string str){
        cout << "重载1:testNew::op new," << str << endl;
        return ::operator new(size);
    }

    void* operator new(size_t size){
        cout << "  重载2:testNe  w::op new,without str"  << endl;
        return ::operator new(size);
    }
    void print(){
        cout << "已初始化成功" << endl;
    }

};

void * operator new(size_t size)
{
    cout << "::op new 内存分配 "<< endl;
    return malloc(size);
}


int main()
{
    
    cout << "重载全局 ::op new" << endl;
    char * buf = (char *)(::operator new((size_t)(sizeof(testNew))));
    cout << endl;

    cout << " placement new" << endl;
    //不加::,会调用 void* testNew:: operator new(size_t size, string str)
    //导致不能匹配全局的placement new
    testNew *test = ::new (buf)testNew;
    test->print();
    test->~testNew();
    delete []buf;
    cout << endl;

    cout << " 重载 testNew::op new 1" << endl;
    //此时输出有4行
    testNew *test2 = new("with str")testNew;

    //::op new 内存分配                -> 给const char* "重载"分配堆空间
    //重载1:testNew::op new,with str  ->调用testNew::op new 1
    //::op new 内存分配                ->testNew::op new 1调用 全局的 ::op new
    //执行了testNew::testNew() 构造函数 
    
    test2->print();               //输出 “已初始化成功” ,表示已正确返回指针
    cout << endl;


    cout << " 重载 testNew::op new 2" << endl;
    testNew *test3 = new testNew;
    test3->print();               //输出 “已初始化成功” ,表示已正确返回指针
    cout << endl;


    cout << "析构" << endl;
    delete test2;
    delete test3;

    getchar();
    return 0;

}

1239821-20180313114559754-2123302325.png

  • 原创所有,转载注明出处,若有错误,欢迎大家指正,共同学习。谢谢!

转载于:https://www.cnblogs.com/pz-Feng/p/8555861.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值