首页 > 解决方案 > 通过引用将指针传递给函数时如何使用与号和星号

问题描述

从 EPI 19.4 开始,问题要求在有向图中找到任何循环。该策略是在 DFS 期间用白色、灰色和黑色来标记节点,这样当两个灰色节点连续迭代时,就会找到一个循环。

我的问题不在于理解策略,而在于使用星号和与号来引用指针并通过引用将指针传递给函数的实现。

struct GraphVertex {
    enum Color { white, gray, black } color = white;
    vector<GraphVertex*> edges; // Line A
};

bool IsDeadlocked(vector<GraphVertex>* G) { // Line B
    return any_of(begin(*G), end(*G), [](GraphVertex& vertex) { // Line C
        return vertex.color == GraphVertex::white && HasCycle(&vertex); // Line D
    });
}

bool HasCycle(GraphVertex* cur) { // Line E
    if (cur->color == GraphVertex::gray) {
        return true;
    }

    cur->color = GraphVertex::gray;
    for (GraphVertex*& next : cur->edges) { // Line F
        if (next->color != GraphVertex::black) {
            if (HasCycle(next)) {
                return true;
            }
        }
    }
    cur->color = GraphVertex::black;
    return false;
}

在 A 行,常见用法,没有问题。

在 B 行,图形表示是vector<GraphVertex>,为什么不是vector<GraphVertex*>?重新阅读后,似乎下面的所有混淆都可以通过使用vector<GraphVertex*>.

在 C 行,begin()/end()将迭代器返回到GraphVertex结构。那么不应该取消引用迭代器来访问GraphVertex结构本身吗?lambda 函数参数是 type GraphVertex&,这是GraphVertex通过引用传递类型吗?但是begin()/end()返回了迭代器,所以 lambda 函数参数的类型不是更有意义GraphVertex*吗?

在 D 行中,&vertex暗示 type 的输入参数GraphVertex&实际上不是指向的指针,GraphVertex而是GraphVertex结构本身,只是现在引用的地址作为指针传递给HasCycle函数,这确实需要指针。然后通过推论,GraphVertex&在 C 行中必须是用于取消引用迭代器以获得类型变量的方法GraphVertex。这个对吗?但是取消引用不是由 完成的GraphVertex*吗?

在 E 行,函数参数是一个指向 的指针GraphVertex,如前所述。

在 F 行,迭代器的类型是GraphVertex*&,它是对指针的引用。这里的&符号确保当GraphVertex*访问元素时,它是实际元素而不是副本。

不幸的是,这里用来描述技术细节的语言是基本的,并且总体上表明缺乏理解。

标签: c++

解决方案


在 C++ 中需要遵循某些约定。

A 行:T*或者std::reference_wrapper<T>都是将对象存储在 中的可接受方式std::vector,当它不拥有元素时。否则T还是std::unique/shared_ptr<T>应该使用。

B、C、D、E 行:在函数中传递只读对象时,应通过 const reference 完成const T&。如果要对对象进行变异,则T&. 应该很少使用原始指针传递。

F 行:这里的引用是多余的。根据定义,指针指向原始数据并且不复制。T*&如果您打算更改指针指向的位置(例如,使其指向新对象),a将是有意义的。

很多这些约定在这里没有使用,这会造成混乱。


推荐阅读