乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 277|回复: 14

[编程交流] AcD bSymbol Tab leIterator和shared_ptr(scoped_ptr)

[复制链接]

27

主题

193

帖子

5

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
300
发表于 2010-2-21 10:00:17 | 显示全部楼层 |阅读模式
这篇文章最初是一个RFC,但是当我写它时,我几乎回答了我自己的问题,现在它或多或少是一个教程。不过,可以将其视为RFC,只是没有问题,因为您可能能够推断出现在非问题的一般要点。
当从大多数ARX api获取新的对象指针时,对象在函数调用中通过引用传递,函数的返回通常是Acad::ErrorStatus。就目前而言,这并不适合非常干净地使用智能指针,并且您最终会得到2个对象,1个用于指针,另一个用于智能指针。
清单 1 是我通常如何处理这个问题,正如你所看到的,有 2 个对象处理同一个迭代器。我必须确保在原始指针传递给智能指针后将其清空,否则在智能指针被销毁后,我可能会使用它。
所以交易是我希望自动处理这个问题,在用不同的方法花了大约一个小时的时间后,我决定列出2和2a。 最重要的是它很简单,并且名称为 AssignToSmartPointer,我一定会只将其与某种智能指针一起使用。
如果由于某种原因智能指针构造函数失败,它将抛出std::bad_alloc,因此只要原始指针是好的并且不抛出std::bad_alloc,那么智能指针就可以安全地被取消引用。
在下面示例的孤立范围内,这是非常简单的东西。但是,在 if 语句 3 或 4 个块级别深处工作时,每一点帮助都会有所帮助。
清单 1
  1.    AcDbLayerTableIterator * pIterator;
  2.    es = pLayerTable->newIterator(pIterator);
  3.    if(es !=  Acad::eOk)
  4.       return es;
  5. [color=navy]   boost::scoped_ptr pIter(pIterator);   // take control of the pointer and set the
  6.    pIterator = NULL;                                             // set the original pointer to 0
  7. [/color]

清单 2
  1.    AcDbLayerTableIterator * pIterator;
  2.    es = pLayerTable->newIterator(pIterator);
  3.    if(es !=  Acad::eOk)
  4.       return es;
  5. [color=navy]
  6.    boost::scoped_ptr pIter(AssignToSmartPointer(pIterator));
  7. [/color]

清单 2a (AssignToSmartPointer 的模板定义)
  1. template
  2. inline T * AssignToSmartPointer(T *& pOriginalPointer)
  3. {
  4.    T * pPtr = pOriginalPointer;
  5.    pOriginalPointer = NULL;
  6.    return pPtr;
  7. }

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

15

主题

190

帖子

5

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
250
发表于 2010-2-21 10:32:21 | 显示全部楼层
我对boost不太熟悉,但是任何获取指针所有权的智能指针都应该有一个构造函数,它接受对非常数指针的引用,然后在所有权转移成功后将原始指针设置为NULL。
回复

使用道具 举报

LE3

10

主题

149

帖子

5

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
189
发表于 2010-2-21 10:40:42 | 显示全部楼层
我总是遵循打开读取表的规则,然后在创建newIterator之后,关闭表,进行扫描,最后删除迭代器,我经常使用智能指针,但从不在这些情况下。
编辑:拼写
回复

使用道具 举报

27

主题

193

帖子

5

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
300
发表于 2010-2-21 15:17:04 | 显示全部楼层

说得好,我回来后会进一步调查。唉,据我所知,shared_ptr模板和家庭不这样做。
回复

使用道具 举报

27

主题

193

帖子

5

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
300
发表于 2010-2-21 15:46:58 | 显示全部楼层

绝对!
提示这样做的原因是,创建迭代器的函数调用了另一个可能引发的函数。因此,所有获取的指针资源都在它们自己的智能指针中。如果抛出函数确实抛出,我希望处理资源,即。在打开的 entites 的情况下删除或关闭(使用 AcDbObjectPointerBase 派生类处理)。 这消除了尝试的需要...捕获块。
回复

使用道具 举报

15

主题

190

帖子

5

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
250
发表于 2010-2-21 17:33:56 | 显示全部楼层

绝对是!
...

但这是不对的,至少根据文档。
回复

使用道具 举报

27

主题

193

帖子

5

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
300
发表于 2010-2-21 17:42:10 | 显示全部楼层

这个怎么样?(有效)
  1. boost::scoped_ptr pIter;
  2. if(pCurBtr->newIterator((AcDbBlockTableRecordIterator*&)pIter) != Acad::eOk)
  3.   ...

回复

使用道具 举报

15

主题

190

帖子

5

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
250
发表于 2010-2-21 19:02:25 | 显示全部楼层
Daniel,我想提到一下,也可以向智能指针类添加一个运算符 T*&(),以便智能指针可以作为参数传递给 newIterator,但这暴露了一个潜在的弱点。如果 newIterator() 函数不返回 Acad::eOk,则指针无效,不应删除。这意味着当返回值不是Acad::eOk时,您必须添加代码来显式释放指针的所有权而不删除它(或者向风抛出警告并假设当函数返回错误时它将始终为NULL)。
回复

使用道具 举报

LE3

10

主题

149

帖子

5

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
189
发表于 2010-2-21 19:53:09 | 显示全部楼层

啊,说得好!我假设(我可能错了)指针总是空的,否则newIterator()函数怎么知道返回什么状态呢?也就是说,要么Autodesk已覆盖new以在失败时返回NULL,要么抛出std::bad_alloc。?。?。
回复

使用道具 举报

27

主题

193

帖子

5

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
300
发表于 2010-2-21 20:50:17 | 显示全部楼层

感谢您指出这一点,因为我有几个程序要去修复,可能很久以前读过,但忘记了(没有注意)。在2005年左右之前,这不会是一个问题,因为我练习了单入口单出口编程,但在某些情况下,调整为具有多个出口点和闭合实体,如Louis所述,这样就不会有6+级嵌套if块。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2024-11-22 02:08 , Processed in 0.270294 second(s), 72 queries .

© 2020-2024 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表