读过Effective C++的进来,这个条款你弄懂了吗?

yanyu2 2014-04-15 06:40:14
条款 10. 如果写了 operator new 就要同时写 operator delete
我按书本的代码进行调试,有几个问题请大家赐教。
下面有代码,问题放在注释那里了,以?问好开头

class AirplaneRep
{
public:
void SetValue(int num){ a = num; }
private:
int a;
};

class Airplane {
public:
static void * operator new(size_t size);
static void operator delete(void *deadObject, size_t size);
void SetPlane(int num);
Airplane *GetNext();
private:
union { // ?1,这里为何使用联合
AirplaneRep *rep;
Airplane *next;
};
static const int BLOCK_SIZE;
static Airplane *headOfFreeList;
};

Airplane *Airplane::headOfFreeList;
const int Airplane::BLOCK_SIZE = 10;

void * Airplane::operator new(size_t size)
{
if (size != sizeof(Airplane))
return ::operator new(size);
Airplane *p = headOfFreeList;// p 指向自由链表的表头
// p 若合法,则将表头移动到它的下一个元素
if (p)
headOfFreeList = p->next;//?2,p不为空为何不用new空间了
else {
// 自由链表为空,则分配一个大的内存块,
Airplane *newBlock =
static_cast<Airplane*>(::operator new(BLOCK_SIZE *
sizeof(Airplane)));
// 将每个小内存块链接起来形成一个新的自由链表
// 跳过第 0 个元素,因为它要被返回给 operator new 的调用者
for (int i = 1; i < BLOCK_SIZE-1; ++i)
newBlock[i].next = &newBlock[i+1];
// 用空指针结束链表
newBlock[BLOCK_SIZE-1].next = 0;
// p 设为表的头部,headOfFreeList 指向的内存块紧跟其后
p = newBlock;
headOfFreeList = &newBlock[1];
}
return p;
}

void Airplane::operator delete(void *deadObject, size_t size)
{
if (deadObject == 0) return;
if (size != sizeof(Airplane)) {
::operator delete(deadObject);
return;
}
Airplane *carcass =
static_cast<Airplane*>(deadObject);//?3,这里是不是漏了delete
carcass->next = headOfFreeList;
headOfFreeList = carcass;
}

int _tmain(int argc, _TCHAR* argv[])
{
Airplane *pa = new Airplane;
//?4,这里怎么给开辟的空间对象的AirplaneRep赋值
delete pa;
return 0;
}
...全文
1007 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
妳是个好人 2014-04-16
  • 打赏
  • 举报
回复
引用 2 楼 u014515312 的回复:
1.这里用联合体,是为了创建一个链表,据我的理解是,你创建的表头是使用*rep成员,之后的是使用*next,而headOfFreeList是指向第一个使用*next节点,也就是实际上的第二个节点. 2.照你说的P已经合法,则你new的内存块已经创建好至少BLOCK_SIZE个Airplane大小,直接返回下一个可用的指针给Airplane::operator new(size_t size)的调用方,让它用已经分配好的内存. 3.不用delete,你程序的意图让你手动调用Airplane::operator delete(size)一次性销毁所有分配内存,否则如果只销毁一个,那实际上是把可用的内存指针headOfFreeList指向要销毁的区域,这样下一次分配的时候这个区域就自动被使用了,而它实际上没有销毁. 4.你声明的是static void * operator new(size_t size); 调用方法应该是Airplane *pa = new(size) Airplane; delete也是如此,你程序中的做法会调用全局的默认::operator new, 不会达到你想要的BLOCK_SIZE效果. 可以参考http://www.cnblogs.com/zhenjing/archive/2011/01/17/class_new.html 整个程序代码太乱了,完全不应该这么做,Scott Meyers的书里有更好的方法替代.
最后一点我说错了, Airplane *pa = new Airplane;会调用Airplane::operator new(size_t size); 另外delete pa; 并不会删除整个BLOCK_SIZE个大小
妳是个好人 2014-04-16
  • 打赏
  • 举报
回复
1.这里用联合体,是为了创建一个链表,据我的理解是,你创建的表头是使用*rep成员,之后的是使用*next,而headOfFreeList是指向第一个使用*next节点,也就是实际上的第二个节点. 2.照你说的P已经合法,则你new的内存块已经创建好至少BLOCK_SIZE个Airplane大小,直接返回下一个可用的指针给Airplane::operator new(size_t size)的调用方,让它用已经分配好的内存. 3.不用delete,你程序的意图让你手动调用Airplane::operator delete(size)一次性销毁所有分配内存,否则如果只销毁一个,那实际上是把可用的内存指针headOfFreeList指向要销毁的区域,这样下一次分配的时候这个区域就自动被使用了,而它实际上没有销毁. 4.你声明的是static void * operator new(size_t size); 调用方法应该是Airplane *pa = new(size) Airplane; delete也是如此,你程序中的做法会调用全局的默认::operator new, 不会达到你想要的BLOCK_SIZE效果. 可以参考http://www.cnblogs.com/zhenjing/archive/2011/01/17/class_new.html 整个程序代码太乱了,完全不应该这么做,Scott Meyers的书里有更好的方法替代.
yanyu2 2014-04-16
  • 打赏
  • 举报
回复
大神都去哪了?
yanyu2 2014-04-16
  • 打赏
  • 举报
回复
引用 3 楼 u014515312 的回复:
[quote=引用 2 楼 u014515312 的回复:] 1.这里用联合体,是为了创建一个链表,据我的理解是,你创建的表头是使用*rep成员,之后的是使用*next,而headOfFreeList是指向第一个使用*next节点,也就是实际上的第二个节点. 2.照你说的P已经合法,则你new的内存块已经创建好至少BLOCK_SIZE个Airplane大小,直接返回下一个可用的指针给Airplane::operator new(size_t size)的调用方,让它用已经分配好的内存. 3.不用delete,你程序的意图让你手动调用Airplane::operator delete(size)一次性销毁所有分配内存,否则如果只销毁一个,那实际上是把可用的内存指针headOfFreeList指向要销毁的区域,这样下一次分配的时候这个区域就自动被使用了,而它实际上没有销毁. 4.你声明的是static void * operator new(size_t size); 调用方法应该是Airplane *pa = new(size) Airplane; delete也是如此,你程序中的做法会调用全局的默认::operator new, 不会达到你想要的BLOCK_SIZE效果. 可以参考http://www.cnblogs.com/zhenjing/archive/2011/01/17/class_new.html 整个程序代码太乱了,完全不应该这么做,Scott Meyers的书里有更好的方法替代.
最后一点我说错了, Airplane *pa = new Airplane;会调用Airplane::operator new(size_t size); 另外delete pa; 并不会删除整个BLOCK_SIZE个大小[/quote] 还不是很懂,不过很感激你的指导

65,208

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧