-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path52.cpp
106 lines (92 loc) · 3.14 KB
/
52.cpp
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//一般所指的placement new
void* operator new(std::size_t, void* pMemory) throw();
//防止构造函数期间的内存泄漏
class Widget
{
public:
...
//一个placement new
static void* operator new(std::size_t size, std::ostream& logStream)
throw(std::bad_alloc);
//提供placement delete,防止operator new成功,构造函数失败时造成的内存泄漏
static void* operator delete(std::size_t size, std::ostream& logStream)
throw();
//operator new正常运行时调用的delete
static void* operator delete(void* pMemory, std::size_t size)
throw();
};
//以下语句如果引发Widget构造函数抛出异常,对应的placement delete会被调用,不会发生内存泄漏
Widget* pw = new (std::cerr) Widget;
//如果没有抛出异常,客户端有如下代码,则会调用正常的delete
delete pw;
//发生函数隐藏
class Base
{
public:
...
static void* operator new(std::size_t size, std::ostream& logStream)
throw (std::bad_alloc); //会掩盖正常的global形式
...
};
Base* pb = new Base; //错误!因为正常的operator new被掩盖
Base* pb = new (std::cerr) Base; //正确,调用Base的placement new
//继承类掩盖全局与基类的new
class Derived : public Base
{
public:
...
//重新声明正常形式的new
static void* operator new(std::size_t size) throw (std::bad_alloc);
...
};
Derived* pb = new (std::clog) Derived; //错误!因为被掩盖了
Derived* pb = new Derived; //正确,调用derived的new
//std中的operator new
void* operator new(std::size_t) throw(std::bad_alloc); //normal new
void* operator new(std::size_t, void*) throw(); //placement new
void* operator new(std::size_t, const std::nothrow_t&) throw(); //nothrow new
//解决名称掩盖
//提供一个基类内含所有的正常形式的new和delete,
class StandardNewDeleteForms
{
public:
//normal new/delete
static void* operator new(std::size_t size) throw(std::bad_alloc)
{
return ::operator new(size); //调用正常的new
}
static void* operator delete(void* pMemory) throw()
{
return ::operator delete(pMemory); //调用正常的delete
}
//placement new/delete
void* operator new(std::size_t size, void* ptr) throw()
{
return ::operator new(size, ptr);
}
void* operator delete(void* pMemory, void* ptr) throw()
{
return ::operator delete(pMemory, ptr);
}
//nothrow new/delete
void* operator new(std::size_t size, const std::nothrow_t& nt) throw()
{
return ::operator new(size, nt)
}
void* operator delete(void* pMemory, const std::nothrow_t& nt) throw()
{
return ::operator new(pMemroy);
}
};
//如果想以自定义形式扩充标准形式,则可利用继承机制及using声明式取得标准形式
class Widget : public StandardNewDeleteForms
{
public:
using StandardNewDeleteForms::operator new; //使这些形式可见
using StandardNewDeleteForms::operator delete;
//添加自定义的placement new/delete,这样就可以在这些函数中调用标准形式的了
static void* operator new(std::size_t size, std::ostream& logStream)
throw(std::bad_alloc);
static void* operator delete(std::size_t size, std::ostream& logStream)
throw();
};