1

我有一个 for 循环,它遍历 XML 文档并找到指定的属性,指向当前节点的指针位于 boost::interprocess::unique_ptr 内,并且有一个自定义删除器来调用对象的release()函数。似乎在每次循环迭代中指针都会被删除,但是release()当这种情况发生时函数会抛出。

有人可以提出解决方案吗?我想过实施一种机制来检查它是否应该被删除,但我不确定我会怎么做......

代码:

typedef bi::unique_ptr<DOMNodeIterator, release_deleter> iterator_ptr;
typedef bi::unique_ptr<DOMNode, release_deleter> node_ptr;

iterator_ptr itera(document->createNodeIterator(rootelement, DOMNodeFilter::SHOW_ALL, NULL, true));

for(node_ptr current(itera->nextNode()); current != 0; current.reset(itera->nextNode())) // throws after one iteration...
{   

……

对象release()

void DOMElementNSImpl::release()
{
    if (fNode.isOwned() && !fNode.isToBeReleased())
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);  // throws here if released after each loop iteration

    DOMDocumentImpl* doc = (DOMDocumentImpl*) fParent.fOwnerDocument;
    if (doc) {
        fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
        fParent.release();
        doc->release(this, DOMMemoryManager::ELEMENT_NS_OBJECT);
    }
    else {
        // shouldn't reach here
        throw DOMException(DOMException::INVALID_ACCESS_ERR,0, GetDOMNodeMemoryManager);
    }
}

删除器:

struct release_deleter
{
    template <typename T>
    void operator()(T* pPtr) const
    {
        pPtr->release();
    }
};

编辑:

virtual DOMNodeIterator *createNodeIterator(DOMNode* root,
                                            DOMNodeFilter::ShowType whatToShow,
                                            DOMNodeFilter* filter,
                                            bool entityReferenceExpansion) = 0;


virtual DOMNode*           nextNode() = 0;
4

1 回答 1

2

我没有用于在工作中编译和调试的visual 2010,只有在家里。所以我不能确定。

但坦率地说,我真的不喜欢迭代器拥有指针的概念。

您的集合拥有指针,迭代器不拥有!它不是它的角色..

在 C++0x 中有一个对 shared_ptr 的补充,即 std::weak_ptr ,您可以从 shared_ptr 构造它,允许查阅和更改数据,但与所有权无关,除非在指针 onwed 时或多或少不可访问由 shared_ptr 释放。

我会为您的迭代器使用一种 std::weak_ptr 。但是对于 unique_ptr,我猜它是一个简单的指向您的数据的指针,它扮演弱引用的角色。

编辑:

DOMNodeIterator * pIter = document->createNodeIterator(rootelement, DOMNodeFilter::SHOW_ALL, NULL, true);

if(pIter==NULL)
{
    return;
}

while(true) // be careful to infinite loops
{
    DOMNode * pNode = pIter->nextNode();
    if (pNode==NULL)
    {
        break;  
    }

    // ... your visiting the nodes here.
}
于 2010-10-27T11:19:20.057 回答