Posted in C/C++ 我抢沙发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <new>
#include <cstdlib>
#define __OUTPUT_FUNC_NAME__ std::cout << __FUNCTION__ \
        <<"\tthis =\t" << this << std::endl;
 
class Foo
{
public:
    Foo()
    {
        __OUTPUT_FUNC_NAME__
    }
    virtual ~Foo()
    {
        __OUTPUT_FUNC_NAME__
    }
};
 
int main()
{
    Foo *psingle = new Foo;
    delete psingle;
 
    std::cout << __LINE__ <<std::endl;
    Foo *psingle_nothrow = new(std::nothrow) Foo();
    delete psingle_nothrow;
 
    std::cout << __LINE__ <<std::endl;
    Foo *parray = new Foo[5];
    delete[] parray;
 
    std::cout << __LINE__ <<std::endl;
    Foo *parray_nothrow = new(std::nothrow) Foo[5];
    delete[] parray_nothrow;
 
    std::cout << __LINE__ <<std::endl;
    Foo *praw = (Foo *)malloc(sizeof Foo);
    new(praw) Foo;
    praw->~Foo();
    free(praw);
 
    std::cout << __LINE__ <<std::endl;
    Foo *praw_array = (Foo *)malloc(sizeof(Foo) * 5);
    for(int i=0; i<5; ++i)
    {
        new(praw_array+i)Foo();
    }
 
    for(int i=0; i<5; ++i)
    {
        (praw_array+i)->~Foo();
    }
    free(praw_array);
 
    return 0;
}

上面这段代码可以用VS2010编译通过并运行。
第7~18行,是一个类Foo,用来示例的。
第22行,是普通的new, 创建单个的对象。如果new分配空间失败,则抛出异常。
第23行,是普通的delete,销毁单个的对象。
第26行,nothrow new,也就是说,当new分配空间失败时,只返回NULL,不会抛出异常。
第30行,new了一个数组。
第31行,将数组delete。
第39行,placement new, 已经有空间了,不用new去分配空间,直接在已经存在的空间上调用构造函数。
第40行,将其销毁。
第44行,申请了一个数组。第45~49行,一个一个地placement new,第50~53行,一个一个地placement delete. 有人会问:为什么不用placement new[], 答:不会,请多指教。

通过以上代码,对new有了直观的认识。new首先会分配空间,然后在得到的空间上调用构造函数。
怎么分配空间?用operator new函数。
分配空间失败了怎么办?如果是普通形式的new,抛出异常;如果是nothrow形式的new,返回NULL。
operator new函数有哪些?且听下回分解。

October 30, 2011