At first
Element* e1, e2;
declare two pointers, then following the creation of two elements with new (on the heap):
e1 = new Element();
e2 = new Element();
which are at the same time assigned to pointers. From now on best try to draw on paper what's going on...
After the assignment, the situation presents itself as:
--------
[e1] -> | [next] +-> <yet invalid!>
--------
--------
[e2] -> | [next] +-> <yet invalid!>
--------
with [...]
indicating the pointers and the arrows the targets. Skipping the names entirely, as likely not relevant.
e1->next = e2;
leads to:
--------
[e1] -> | [next] |
---|----
v
--------
[e2] -> | [next] +-> <yet invalid!>
--------
then
e2->next = e1;
to
--------
[e1] -> | [next] |
--|----
v ^
-----|--
[e2] -> | [next] +-> <yet invalid!>
--------
and finally
e1 = e2;
results in
--------
[e1] - | [next] |
| --|----
| v ^
-> -----|--
[e1] --> | [next] +-> <yet invalid!>
--------
Note how two pointers now keep the address of the same data object, while the other one can be accessed via the first one's next pointer.
Note, too, that the code as presented results in two memory leaks as the two objects created with new
are never delete
d again.
Edit: About new
:
new SomeType
(optionally with parentheses which then contains, if need be, the parameters you wish to pass to the type's constructor) is a special operation with in C++; it does several things:
- It allocates sufficient memory for the object that shall be constructed. The type identifier (
SomeType
) provides the information for which type memory shall be allocated (in your question for an ojbect of type Element
which needs to be able to hold the memory a std::string
requires and additionally a pointer).In case this allocation fails, an exception of type std::bad_alloc
is thrown (unless you use the special no-throw variant – now going into detail on, though).
- It calls the constructor providing to it the address of the memory allocated just before; the constructor does the necessary initalisation as defined (in your case there's a default constructor initialising an empty string and actually not doing anything to the pointer, which is why it remains invalid).
- Returns the memory address, which is what makes the assignment to a pointer possible at all.
These are the very basics of the language, any good C++ book should explain them just as well.
Be aware, though, that in modern C++ you'd prefer smart pointers over raw pointers, relieving you from manual memory management (mainly from the need to call delete
explicitly).