http://efesx.com/2009/12/01/public-operator-new-and-private-operator-delete/
在本文中,我读到此代码应该出错:
#include <cstdlib>
struct Try {
Try () { /* o/ */ }
void *operator new (size_t size) {
return malloc(size);
}
private:
void operator delete (void *obj) {
free(obj);
}
};
int main () {
Try *t = new Try();
return 0;
}
我用gcc 4.7.1尝试了它:
Compilation finished with errors: source.cpp: In function 'int
main()': source.cpp:11:14: error: 'static void Try::operator
delete(void*)' is private source.cpp:17:22: error: within this context
source.cpp:11:14: error: 'static void Try::operator delete(void*)' is
private source.cpp:17:22: error: within this context source.cpp:17:10:
warning: unused variable 't' [-Wunused-variable]
在本文的评论中,我看到了这个链接 - Public operator new, private operator delete: getting C2248 "can not access private member" when using new
如果我unserstand它是正确的,它不会编译,因为编译器应该避免在构造函数通过调用适当的operator delete抛出异常的情况下的任何内存泄漏。但为什么这段代码编译和工作?
#include <cstdlib>
struct Try {
void *operator new (size_t size) {
return malloc(size);
}
private:
void operator delete (void *obj) {
free(obj);
}
};
int main () {
Try *t = new Try;
return 0;
}
标准是否正确?
这段代码怎么样?
#include <cstdlib>
struct Try {
void *operator new (size_t size) {
return malloc(size);
}
private:
void operator delete (void *obj) {
free(obj);
}
};
int main () {
Try *t = new Try();
return 0;
}
它不能用gcc 4.7.1编译。
这样的事情应该如何在标准库中实现?
Comeau没有编译所有这些例子:
"ComeauTest.c", line 15: error: function "Try::operator delete"
(declared at line 9) is inaccessible Try *t = new Try; ^
有人可以详细解释一下吗?
答案 0 :(得分:2)
第二和第三个例子涉及POD类型。 initialization differences扮演角色。
在第二个示例中,您的结构离开未初始化。没问题出现。
相反,在第三个示例结构中, 进行初始化,因此您得到第一个案例。
修改强>
然后,operator new
本身可以抛出异常。标准(c ++ 11 darft说):
如果
new
表达式通过抛出异常终止,它可能会 通过调用释放功能释放存储(3.7.4.2)。如果 assign type是非数组类型,分配函数的名称是operator new
和解除分配函数的名称为operator delete
。
有点不清楚,作者想要表达的是可能释放存储。如果 发布,它似乎是实现定义的。
无论如何,您可以尝试使用not-throwing new
版本:
void *operator new (size_t size, std::nothrow_t) throw() {
return malloc(size);
}
答案 1 :(得分:0)
编译器创建构造函数代码,如果构造函数代码抛出异常,也会涉及运算符 new 和 delete 。因此,使用新会自动创建删除的使用。
在第二个例子中,编译器知道你使用的默认构造函数从不抛出(我的猜测)..
不同的编译器以不同的方式工作,因为它们不同(队长)并且具有不同的优化功能和创建代码的技巧