【问题标题】:help with c++ classes, pointers n such帮助 c++ 类,指针 n 这样
【发布时间】:2011-07-17 18:33:45
【问题描述】:

我有一个项目,我正在使用 C++ 类实现 Dijkstra 的最短路径算法。它使用 OpenGL,但这肯定与我的问题是分开的。我需要了解我在 Dijkstra 类方法中做错了什么。这是我的相关代码:

class Node {
    public: 
        GLfloat x, y, z;
        int numLinks;
        Node *link1;
        Node *link2;
        GLfloat distance;
        Node *previous;

        Node(GLfloat x, GLfloat y, Node *link1, Node *link2);
        Node(GLfloat x, GLfloat y, Node *link1);
        Node();
        Node(GLfloat x, GLfloat y);
        ~Node();

        bool dijkstra(Node* graph[], Node *source, Node *target); //returns true if a path to target is found
        int dist(Node &n1, Node &n2);
};

int Node::dist(Node &n1, Node &n2) {
    GLfloat d = sqrt((pow((n2.x - n1.x), 2)) + (pow((n2.y - n1.y), 2)));
    return d;
}

bool Node::dijkstra(Node* graph[], Node *source, Node *target) {
    queue<Node> q;
    int i;
    for (i = 0; i < NUM_NODES; i++) {
        graph[i]->distance = INFIN;
    }
    source->distance = 0;   
    i = 0;
    q.push(*source);
    while (!q.empty()) {
        Node temp = q.front();

        GLfloat d1 = dist(temp, temp->link1);
        GLfloat d2 = dist(temp, temp->link2);
        temp.link1.distance = d1;
        temp.link1.distance = d2;

        GLfloat alt = temp.distance + temp->link1.distance;
        if (alt < temp->link1.distance) {
            temp->link1.distance = alt;
            temp->previous = temp;
        }

        alt = temp->distance + temp->link2->distance;
        if (alt < temp->link2->distance) {
            temp->link2->distance = alt;
            temp->previous = temp;
        }

        if(d1 > d2) {
            q.push(temp->link2);
            q.push(temp->link1);
        } else {
            q.push(temp->link1);
            q.push(temp->link2);
        }
        q.pop();
        i++;
    }

    return true;
}

我的猜测是我正在使用“->”和“。”运营商都错了。当我尝试编译时,我得到了很多这样的错误:

error: base operand of ‘->’ has non-pointer type ‘Node’

我对 Dijkstra 算法的实现进行了一些改进以满足我的需要,并且可能是错误的,但我需要编译它以便调试它。

列出的代码是唯一让我感到悲伤的代码,但如果您想查看其中的另一部分,请询问。非常感谢我做错了什么的一个很好的解释。

【问题讨论】:

  • Dijkstra 的算法不是你眼前的问题。您可能想选择一本好的 C++ 书籍并首先熟悉基础知识。它肯定会帮助您并解决您遇到的大部分问题。

标签: c++ class pointers


【解决方案1】:

通过指针访问数据时应该使用'->'操作符。否则,您应该使用“。”运算符。

例如下面这几行是相同的

Node *node = &q.front();

(*node).link1->distance = 1;
node1->link1->distance = 1;

至于您的编译问题,问题在于您如何访问 temp。 temp 声明为

Node temp = q.front();

这意味着 temp 是队列前面节点的 副本,而不是指向它的指针。这就是为什么当您尝试像访问指针一样访问它时编译器会抱怨的原因。例如:

temp->link1.distance = alt;

应该看起来像

temp.link1->distance = alt;

因为 temp 不是指针,但 link1 是。

【讨论】:

  • 是的,我想通了并编译了它,但是如果你不介意的话,一个简单的问题,通过复制 q.front(),这是否意味着我对 temp 所做的任何事情都不是将传播到 q.front() 中的任何内容?
  • 没错,q.front() 将返回队列前面的副本,因此对其所做的任何更改都不会反映在队列的内部副本上。如果您有一个指向对象的指针队列,那么 q.front() 会将您指向将被修改的实际对象。如果你走这条路,别忘了在必要时释放你的记忆。
【解决方案2】:

关于您的设计的一些问题:

dijkstra真的是可以应用于节点的方法吗?

似乎这是一个应用于整个图形的操作。

class Graph
{
    std::vector<NodeId> dijkstra(NodeId const& start, NodeId const& target);
};

什么是previous

节点似乎有一些内部指针,仅用于算法Node *previous; 该节点不应包含此类信息。

Line1/Link2

这是否意味着节点只能链接到其他两个节点。这看起来不像是图表,更像是一棵树?

class Node
{
    std::vector<LinkId>   links;
};

所以我的出发点是:

class Graph
{
    class Link
    {
          NodeId   src;
          NodeId   dst;
          float    dist; // only calculate once for each link
    };
    class Node
    {
          float   x,y;
          std::vector<boost::shard_ptr<Link> >   links;
    };
    typedef  std::vector<Node>   GraphContainer;
    GraphContainer   graphPoints;

    public:
       typedef GraphContainer::size_type  NodeId;

       NodeId   addNode(float x, float y);
       void     link(NodeId& p1, NodeId& p2);

       std::vector<NodeId> dijkstra(NodeId const& start, NodeId const& target);
};

现在写得干净利落应该会简单很多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多