zoukankan      html  css  js  c++  java
  • 46、C++中有几种类型的new

    在C++中,new有三种典型的使用方法:plain new,nothrow new和placement new

    (1)plain new

    言下之意就是普通的new,就是我们常用的new,在C++中定义如下:

    因此plain new在空间分配失败的情况下,抛出异常std::bad_alloc而不是返回NULL,因此通过判断返 回值是否为NULL是徒劳的,举个例子:

    #include <iostream>
    #include <string>
    using namespace std;
    int main()
    {
    try
    {
    char *p = new char[10e11];
    delete p;
    }
    catch (const std::bad_alloc &ex)
    {
    cout << ex.what() << endl;
    }
    return 0;
    }
    //执行结果:bad allocation

    (2)nothrow new

    nothrow new在空间分配失败的情况下是不抛出异常,而是返回NULL,定义如下:

     

     举个例子:

    #include <iostream>
    #include <string>
    using namespace std;
    int main()
    {
    char *p = new(nothrow) char[10e11];
    if (p == NULL)
    {
    cout << "alloc failed" << endl;
    }
    delete p;
    return 0;
    }
    //运行结果:alloc failed

    (3)placement new

    这种new允许在一块已经分配成功的内存上重新构造对象或对象数组。placement new不用担心内存分 配失败,因为它根本不分配内存,它做的唯一一件事情就是调用对象的构造函数。定义如下: 

     使用placement new需要注意两点:

    1.palcement new的主要用途就是反复使用一块较大的动态分配的内存来构造不同类型的对象或者 他们的数组

    2.placement new构造起来的对象数组,要显式的调用他们的析构函数来销毁(析构函数并不释放 对象的内存),千万不要使用delete,这是因为placement new构造起来的对象或数组大小并不 一定等于原来分配的内存大小,使用delete会造成内存泄漏或者之后释放内存时出现运行时错误。

    #include <iostream>
    #include <string>
    using namespace std;
    class ADT{
    int i;
    int j;
    public:
    ADT(){
    i = 10;
    j = 100;
    cout << "ADT construct i=" << i << "j="<<j <<endl;
    }
    ~ADT(){
    cout << "ADT destruct" << endl;
    }
    };
    int main()
    {
    char *p = new(nothrow) char[sizeof ADT + 1];
    if (p == NULL) {
    cout << "alloc failed" << endl;
    }
    ADT *q = new(p) ADT; //placement new:不必担心失败,只要p所指对象的的空间足够ADT创建即可
    //delete q;//错误!不能在此处调用delete q;
    q->ADT::~ADT();//显示调用析构函数
    delete[] p;
    return 0;
    }
    //输出结果:
    //ADT construct i=10j=100
    //ADT destruct
    #include <iostream>
    #include <string>
    using namespace std;
    int main()
    {
    try
    {
    char *p = new char[10e11];
    delete p;
    }
    catch (const std::bad_alloc &ex)
    {
    cout << ex.what() << endl;
    }
    return 0;
    }
    //执行结果:bad allocation
  • 相关阅读:
    python两个装饰器的运算顺序
    python中私有属性的访问
    python中的方法使用
    创业,宁愿单兵作战也不要参在拙劣的团队里继续寻觅队友
    项目经理问:为什么总是只有我在加班 – 挂包袱现象
    我该怎么安排下属的工作-项目经理如何分配任务
    项目经理自己要写代码吗?
    管理系统书籍《从程序员到项目经理》 从程序员到项目经理(一)
    宗宁:赚快钱的那些坑。。(转载)
    java 实现二分法
  • 原文地址:https://www.cnblogs.com/crbhf/p/15087080.html
Copyright © 2011-2022 走看看