I have a simple C++ class that uses generic templates to store and retrieve generic variables. Storing them is no issue but returning the generic variable returns a hexadecimal value.
Could someone tell me why it’s doing that?
node.h
#pragma once
#include <iostream>
template <typename T>
class Node {
private:
T data;
Node *next_node;
public:
Node(T data) {
this->data = data;
std::cout << "Node with data - " << this->data << " - has been created." << std::endl;
}
T get_data() {
return this->data;
}
void set_next_node(Node next) {
this->next_node = next;
}
Node get_next_node() {
return this->next_node;
}
};
main.cpp
#include <iostream>
#include "node.h"
int main() {
Node node = new Node("Hello World");
std::cout << "Node data: " << node.get_data() << std::endl;
return 0;
}
output
gabriel@desktop:/media/gabriel/main/repositories/CPP Sandbox/nodes$ g++ main.cpp -o main
gabriel@desktop:/media/gabriel/main/repositories/CPP Sandbox/nodes$ ./main
Node with data - Hello World - has been created.
Node with data - 0x55ec552d3eb0 - has been created.
Node data: 0x55ec552d3eb0
>Solution :
The problem you are facing is that you are using new
to create a node but then trying to assign the pointer returned to a non-pointer Node
variable.
This line is the problem:
Node node = new Node("Hello World");
What this does is to first construct an unnamed Node
object with a template type of const char *
; then, by using the pointer to that new object to initialize your node
variable, you are constructing a second Node
object, with the deduced template type being Node*
. The cout
lines showing hexadecimal values are correctly displaying the address value stored in that second, named Node
variable.
You can get round this in several ways. The easiest is to not use the new
operator:
Node node{ "Hello World" }; // Construct object directly
Another way would be to continue using the new
call but then make your node
a pointer:
int main()
{
Node<const char*>* node = new Node("Hello World"); // Or auto node = new Node("Hello World");
std::cout << "Node data: " << node->get_data() << std::endl; // Now we need "->" instead of the "."
delete node;
return 0;
}
The first line of code in your main
function is, effectively, doing this:
Node node{ new Node("Hello World") };
Thus creating two nodes with the named one having it’s template type as Node<const char*>*
. Or, to put it another way, your first line is equivalent to the following, with explicit template types:
Node< Node<const char*>* > node = new Node<const char*>("Hello World");
Also note that the =
operator here is not an assignment but an initialization; this is why the constructor is called.