Cliffnotes:
I've gotten method chaining to work as I expected in one case, but in another case, there is something funny going on.
I expect these two example to have the exact same output:
As expected example
Not as expected example
I've done a lot of chaining using Javascript, so when I learned that you can chain class methods in a similar way in C++, I wanted to give it a try. I ran into some problems though. I'm not sure if it's the chaining causing the problems, or something else.
I'm doing the chaining by returning references to this
. For example:
Class LLL
{
public:
LLL & addNode( ... );
and then the add Node method ends with:
...
return *this;
}
There's 2 pertinent classes and 3 pertinent methods.
I have a linear linked list class, LLL
and a Node classs, Node
. To keep this as simple as possible a node simply holds an int
(called guid
) and a next
and prev
pointer. A linear linked list puts a bunch of nodes in a LLL. This all works fine, but when I add nodes using chaining I sometimes get odd results.
An example where things work like I expect:
// 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
Now I wanted to try it with just one node object:
An example where I don't understand what is going on:
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
It seems like the two examples above should have identical results.
I think I must be misunderstanding something about what happens to the single node object in the second example.
You can look at the code in either of the codepads above, and I'll include the complete code for the second example below. I set up the code to be one huge file, so that I can put it on codepad, but I'll comment in what would be node.h
, node.cpp
, lll.h
, lll.cpp
, and 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
=============================================================================*/