0

Trying to edit a node in a linked list, the "next node" is inside the private section of my node class, i added a method which only returns the Node* in the public in order to edit it when i need to, and i get an error it's modifiable.

Before i moved the next node pointer to the private section it was inside my public section and worked fined, i don't understand what's the difference between editing the "Node* next" directly or editing "Node* getNext()" which returns exactly the same thing, the Node* next.

Here's some of the relevant code:

class Node;

//Node class
class Node
{
private:
    Client* client;
    Node* next;
public:
    Node();
    Node(Client*);
    Node(Client*,Node*);
    ~Node();

    Client* getClient();
    Node* getNext();
};
//end of Node class

The getters:

Client* MatchmakingAgency::Node::getClient(){
    return client;
}

MatchmakingAgency::Node* MatchmakingAgency::Node::getNext(){
    return next;
}

and the function that returns the error: (2nd line)

void MatchmakingAgency::addNode(Client* data){
    (nodeTail->getNext()) = new Node(data);
    nodeTail = nodeTail->getNext();
}

Error message:

Error 1 error C2106: '=' : left operand must be l-value

argamanza
  • 1,122
  • 3
  • 14
  • 36

3 Answers3

4

You are returning a copy of the data member, and, since it is a built-in type, you cannot modify it. If you want to modify a data member via a "getter", you need to return a reference to said member:

Node*& getNext();

It is common practice to privide const overloads for this kind of member function:

const Node*& getNext() const;

Of course, this begs the question: why not use a public data member? There may be good reasons to make the member private, but it is worth thinking about this. If you are not maintaining any invariants, or conforming to some "interface", or don't think you need to provide some non trivial implementation of the access methods, you could use a public data member.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
2

The error is that your getter is returning a COPY of the next ptr. So if you modify the copy of the next pointer like you're doing.

(nodeTail->getNext()) = new Node(data);

You're modifying the wrong thing.

A fix (which is a hack really) to this would be to try changing your getNext to return the actual next reference:

MatchmakingAgency::Node*& MatchmakingAgency::Node::getNext(){
    return next;
}
shafeen
  • 2,431
  • 18
  • 23
1

As the link( http://msdn.microsoft.com/en-IN/library/f90831hc.aspx ) at MSDN says:

An lvalue refers to an object that persists beyond a single expression. You can think of an lvalue as an object that has a name. All variables, including nonmodifiable (const) variables, are lvalues.

The call

 (nodeTail->getNext()) = new Node(data);

is wrong syntactically as the expression is

(nodeTail->getNext())

is not an lvalue due to your declaration of the function as

Node* getNext();    

. In order to make it an lvalue, you would have to make it an lvalue by using the Lvalue Reference Declarator: &, i.e.

define the getter as

Node*& getNext();

To read more about lvalues, see this stackoverflow link:

What are rvalues, lvalues, xvalues, glvalues, and prvalues?

Community
  • 1
  • 1
bhuwansahni
  • 1,834
  • 1
  • 14
  • 20