代码之家  ›  专栏  ›  技术社区  ›  Peter Ajtai

链接方法给了我意想不到的结果,参数的计算顺序是相反的。

  •  3
  • Peter Ajtai  · 技术社区  · 14 年前

    Cliffnotes:

    我已经让方法链如我所料在一种情况下工作,但在另一种情况下,有一些有趣的事情正在发生。

    我希望这两个示例具有完全相同的输出:
    As expected example
    Not as expected example


    我已经使用JavaScript做了很多链接,所以当我了解到你可以用类似的方式在C++中链接类方法时,我想尝试一下。不过,我遇到了一些问题。我不确定是不是链子造成了问题,还是其他什么原因。

    我通过返回引用来链接 this . 例如:

    Class LLL
    {
    public:
        LLL & addNode( ... );
    

    然后,添加节点方法以以下内容结束:

        ...
        return *this;
    }
    

    有2个相关类和3个相关方法。

    我有一个线性链表类, LLL 和一个节点类, Node . 为了尽可能简单地保持这一点,节点只需 int (被称为 guid 和A next prev 指针。线性链表将一组节点放入LLL中。这一切都很好,但是当我使用链接添加节点时,有时会得到奇怪的结果。


    如我所期望的那样工作:

        // Create 3 node objects & change their guids
    Node node1; node1.change(1); // change(n) outputs "-n-"
    Node node2; node2.change(2);
    Node node3; node3.change(3);
    
        // Create a linear linked list object
    LLL lll;
        // Add the nodes to the LLL and show the LLL
    lll.addNode(node1).addNode(node2).addNode(node3).show();
    
    // Expected and real output:
    -1--2--3-123 
    

    Try it out with this Codepad

    现在我只想用一个节点对象来尝试它:


    一个我不明白发生了什么的例子:

    Node nod;
    LLL lll;
    lll.addNode(nod.change(1)).addNode(nod.change(2)).addNode(nod.change(3)).show();
    
    // Expected output:
    -1--2--3-123
    // Output:
    -3--2--1-111 
    
    // Why are the changes being made in reverse order? And why do all three
    //    nodes have a guid of 1?
    

    Try it out with this Codepad

    上面的两个例子似乎应该有相同的结果。

    我想我一定是对第二个例子中的单节点对象发生了什么误解。

    您可以在上面的代码板中查看代码,我将在下面的第二个示例中包含完整的代码。我把代码设置为一个大文件,这样我就可以把它放在代码板上,但是我会在 node.h , node.cpp , lll.h , lll.cpp main.cpp :

    #include <cstdlib>
    #include <iostream>
    #include <cstring>
    #include <ctime>
    using namespace std;
    
    // NODE.H ======================================================================*/
    // This class holds the data
    class Node
    {
    public:
        Node();
        Node(int guidIn);
        Node(const Node & nodeIn);
        Node & change(int guidIn);
        void commonConstructor();
        // Get the next node
        Node * next();
        // Set the next node
        void   next(Node * nodeIn);
        // Get the previous node
        Node * prev();
        // Set the previous node
        void   prev(Node * nodeIn);
        Node & show();
    private:
        int guid;
        Node * nextNode;
        Node * prevNode;
    };
    /* EOF
       =============================================================================*/
    
    // LLL.H =======================================================================*/
    // This is a LLL to hold nodes
    class LLL
    {
    public:
        LLL();
        ~LLL();
        LLL & addNode(const Node & nodeIn);
        LLL & show();
    private:
        Node * head;
    };
    /* EOF
       =============================================================================*/
    
    // NODE.CPP ====================================================================*/
    Node::Node()
    {
        guid = 0;
        commonConstructor();
    }
    Node::Node(int guidIn)
    {
        guid = guidIn;
        commonConstructor();
    }
    Node::Node(const Node & nodeIn)
    {
        guid = nodeIn.guid;
        commonConstructor();
    }
    Node & Node::change(int guidIn)
    {
        guid = guidIn;
        cout << "-" << guidIn << "-";
        return *this;
    }
    void Node::commonConstructor()
    {
        nextNode = NULL;
        prevNode = NULL;
    }
    Node * Node::next()
    {
        return nextNode;
    }
    void Node::next(Node * nodeIn)
    {
        nextNode = nodeIn;
    }
    Node * Node::prev()
    {
        return prevNode;
    }
    void Node::prev(Node * nodeIn)
    {
        prevNode = nodeIn;
    }
    Node & Node::show()
    {
        cout << guid;
        return *this;
    }
    /* EOF
       =============================================================================*/
    
    // LLL.CPP =====================================================================*/    
    LLL::LLL()
    {
        head = NULL;
    }
    LLL::~LLL()
    {
        Node * temp = head;
        while(head)
        {
            temp = head;
            head = head->next();
            delete temp;
        }
    }
    LLL & LLL::addNode(const Node & nodeIn)
    {
        Node * tempNode = new Node(nodeIn);
        if(!head)
        {
            head = tempNode;
        } else
        {
            Node * temp = head;
            while(temp->next())
            {
                temp = temp->next();
            }
            temp->next(tempNode);
        }
        return *this;
    }
    LLL & LLL::show()
    {
        Node * temp = head;
        while(temp)
        {
            temp->show();
            temp = temp->next();
        }
        return *this;
    }
    /* EOF
       =============================================================================*/
    
    // MAIN.CPP ====================================================================*/    
    int main()
    {
        Node node;
        LLL lll;
        lll.addNode(node.change(1)).addNode(node.change(2))
            .addNode(node.change(3)).show();
    
        cout << "\n";
        return 0;
    }
    /* EOF
       =============================================================================*/
    
    3 回复  |  直到 14 年前
        1
  •  4
  •   Marcelo Cantos    14 年前

    a.f(b) A::f(a, b) a A b

    a.foo(b.bar(1)).foo(b.bar(2)) a.foo(b.bar(1)) b.bar(2) foo

        2
  •  2
  •   Benjamin Lindley    14 年前

    lll.addNode(   // fourth
    node.change(1) // third
    )
    .addNode(      // fifth
    node.change(2) // second
    )
    .addNode(      // sixth
    node.change(3) // this is first
    )
    .show();       // last
    

        3
  •  0
  •   Tomek    14 年前