关于new的定位表达式的疑问.
关于new的定位表达式的疑问.
如果申请了一块char*内存, 用char *p指向它, char *p = new char[SIZE];
然后用new的定位表达式将对象全部在p中生成, char *pT = new (p) T[SIZE/20];
那么new出来的对象怎么析构?
用单独先delete掉对象, 然后再delete掉这块p指向的char*的内存吗?
我看C++Primer中写的, 是不用delete掉对象, 直接delete掉char*的内存.
但是如果对象中包含指针数据成员, 可能关联到别的内存区, 也可能关联到系统资源,
那么它们是怎么被析构的?
我写了一段代码, 发现并没有调用析构函数:
//另外, 发现在BCC下没有编译通过, 提示new表达式出错, 提示:Could not find a match for 'operator new[](unsigned int, char *)'
//在GCC(版本3.2.3)下, 也没有通过, 需把int i = sizeof T;这句改成int i = sizeof(T);不清楚为什么.
//VC和VS2003下, 顺利通过.
#include <iostream>
#include <new>
using namespace std;
class T {
public:
T() {
cout<<"T"<<endl;
}
~T() {
cout<<"~T"<<endl;
}
};
int main()
{
int i = sizeof T;
char *p = new char[i * 1000];
T *pT = new (p) T[20];
delete []p;
return 0;
}
问题点数:20、回复次数:2Top
1 楼ox_thedarkness()回复于 2006-03-05 01:22:31 得分 20
1 replacement new 不能delete。
2 应该手动调用其析构函数。
参考 Thinking in C++第一版 12.5.5 或者 More Effective C++ 条款8,第39~41面Top
2 楼ox_thedarkness()回复于 2006-03-05 01:41:50 得分 0
ISO C/C++规定sizeof 这样使用:
当a是对象时,用 sizeof a 或 sizeof (a)
当a是类型时,只能用 sizeof (a)
BCC没用过,如果不支持replacement new 大概是太老了
更标准的做法是,用全局版 operator new 申请 raw (生鲜)内存。
注意手动析构时,应该模仿C++默认行为,以和构造相反的顺序调用析构函数。虽然大部分不至于出错,但是养成这个习惯可以避免未来潜在的麻烦。
class T {
int i;
public:
T() {
static int n;
i = n++;
cout<<"T() #"<<i<<endl;
}
~T() { cout<<"~T() #"<<i<<endl;}
};
int main(){
void *p = operator new( sizeof T() * 1000);
T *pT = new (p) T[20];
for( int i = 20-1; i>= 0; --i )
pT[i].~T();
delete p;
}
Top




