AcD bSymbol Tab leIterator和shared_ptr(scoped_ptr)
这篇文章最初是一个RFC,但是当我写它时,我几乎回答了我自己的问题,现在它或多或少是一个教程。不过,可以将其视为RFC,只是没有问题,因为您可能能够推断出现在非问题的一般要点。当从大多数ARX api获取新的对象指针时,对象在函数调用中通过引用传递,函数的返回通常是Acad::ErrorStatus。就目前而言,这并不适合非常干净地使用智能指针,并且您最终会得到2个对象,1个用于指针,另一个用于智能指针。
清单 1 是我通常如何处理这个问题,正如你所看到的,有 2 个对象处理同一个迭代器。我必须确保在原始指针传递给智能指针后将其清空,否则在智能指针被销毁后,我可能会使用它。
所以交易是我希望自动处理这个问题,在用不同的方法花了大约一个小时的时间后,我决定列出2和2a。 最重要的是它很简单,并且名称为 AssignToSmartPointer,我一定会只将其与某种智能指针一起使用。
如果由于某种原因智能指针构造函数失败,它将抛出std::bad_alloc,因此只要原始指针是好的并且不抛出std::bad_alloc,那么智能指针就可以安全地被取消引用。
在下面示例的孤立范围内,这是非常简单的东西。但是,在 if 语句 3 或 4 个块级别深处工作时,每一点帮助都会有所帮助。
清单 1
AcDbLayerTableIterator * pIterator;
es = pLayerTable->newIterator(pIterator);
if(es !=Acad::eOk)
return es;
boost::scoped_ptr pIter(pIterator); // take control of the pointer and set the
pIterator = NULL; // set the original pointer to 0
清单 2
AcDbLayerTableIterator * pIterator;
es = pLayerTable->newIterator(pIterator);
if(es !=Acad::eOk)
return es;
boost::scoped_ptr pIter(AssignToSmartPointer(pIterator));
清单 2a (AssignToSmartPointer 的模板定义)
template
inline T * AssignToSmartPointer(T *& pOriginalPointer)
{
T * pPtr = pOriginalPointer;
pOriginalPointer = NULL;
return pPtr;
}
**** Hidden Message ***** 我对boost不太熟悉,但是任何获取指针所有权的智能指针都应该有一个构造函数,它接受对非常数指针的引用,然后在所有权转移成功后将原始指针设置为NULL。 我总是遵循打开读取表的规则,然后在创建newIterator之后,关闭表,进行扫描,最后删除迭代器,我经常使用智能指针,但从不在这些情况下。
编辑:拼写
说得好,我回来后会进一步调查。唉,据我所知,shared_ptr模板和家庭不这样做。
绝对!
提示这样做的原因是,创建迭代器的函数调用了另一个可能引发的函数。因此,所有获取的指针资源都在它们自己的智能指针中。如果抛出函数确实抛出,我希望处理资源,即。在打开的 entites 的情况下删除或关闭(使用 AcDbObjectPointerBase 派生类处理)。 这消除了尝试的需要...捕获块。
绝对是!
...
但这是不对的,至少根据文档。
这个怎么样?(有效)
boost::scoped_ptr pIter;
if(pCurBtr->newIterator((AcDbBlockTableRecordIterator*&)pIter) != Acad::eOk)
...
Daniel,我想提到一下,也可以向智能指针类添加一个运算符 T*&(),以便智能指针可以作为参数传递给 newIterator,但这暴露了一个潜在的弱点。如果 newIterator() 函数不返回 Acad::eOk,则指针无效,不应删除。这意味着当返回值不是Acad::eOk时,您必须添加代码来显式释放指针的所有权而不删除它(或者向风抛出警告并假设当函数返回错误时它将始终为NULL)。
啊,说得好!我假设(我可能错了)指针总是空的,否则newIterator()函数怎么知道返回什么状态呢?也就是说,要么Autodesk已覆盖new以在失败时返回NULL,要么抛出std::bad_alloc。?。?。
感谢您指出这一点,因为我有几个程序要去修复,可能很久以前读过,但忘记了(没有注意)。在2005年左右之前,这不会是一个问题,因为我练习了单入口单出口编程,但在某些情况下,调整为具有多个出口点和闭合实体,如Louis所述,这样就不会有6+级嵌套if块。
页:
[1]
2