sel*_*bie 5 c++ dictionary pointers this-pointer
我们来看一个表示子节点树的数据结构(Node)的示例.每个对象的子节点集存储在map>中
class Node;
typedef std::shared_ptr<Node> NodePtr;
class Node
{
    std::map<const std::string, NodePtr> _childNodes;
    void SomeOtherMethod();
public:
    bool GetChildByKeyName(/*In*/ const std::string& key, /*Out*/ NodePtr& spChild)
    {
        bool result = false;
        auto itor = _childNodes.find(key);
        if (itor != _childNodes.end())
        {
            spChild = itor->second;
            result = true;
            SomeOtherMethod();
        }
        return result;
    }
};
以下代码示例作为用户通常会调用它.
NodePtr spNode, spChildNode;
bool result;
...
result = spNode->GetChildByKeyName(strChildKeyName, spChildNode);
到现在为止还挺好.
在我看来,调用者可能会遍历树而不必为树中的每个深度处理额外的变量
NodePtr spNode;
bool result;
result = spNode->GetChildItem(strChildKeyName, spNode);
if (result)
   spNode->GetChildItem(strSubKeyName, spNode);
在上面的例子中,如果spNode是对象的最后剩余引用,那么我担心GetChildItem方法中的这段代码:
            spChild = itor->second;
            result = true;
            SomeOtherMethod();
spChild(实际上是调用者的spNode实例)的赋值是否因为最后一个引用消失而无意中破坏了"this"节点?(因此在spChild赋值之后调用其他方法是危险的).我这里有潜在的错误吗?
我认为解决方法是简单地在方法调用的顶部添加这一行:
NodePtr spChildRef = spChild; // maintain a reference to the caller's original node during the scope of the method
思考?
你是对的,如果你的第二个例子中最外面的spNode指针是对根项的唯一引用,GetChildByKeyName将替换该引用,导致对象被破坏(实质上是"删除它").
我意识到这可能不是完整的代码,可能有理由为什么你这样设计它,但我个人建议更改界面以返回找到的子而不是使用out参数.(您仍然可以通过测试null来区分找到孩子的成功和失败.)
实际查找代码不仅变得更简单:
NodePtr GetChildByKeyName(/*In*/ const std::string& key)
{
    auto itor = _childNodes.find(key);
    if (itor != _childNodes.end())
    {
        SomeOtherMethod();
        return itor->second;
    }
    return nullptr;
}
然后,您还可以重复使用指向心脏内容的指针:
NodePtr spNode; 
....
spNode = spNode->GetChildItem(strChildKeyName);
if (spNode)
    spNode = spNode->GetChildItem(strSubKeyName);