C++ 模板为何返回十六进制值?

Gab*_*lov 3 c++

我有一个简单的 C++ 类,它使用通用模板来存储和检索通用变量。存储它们没有问题,但返回通用变量会返回十六进制值。

有人能告诉我为什么这样做吗?

节点.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;
        }
};
Run Code Online (Sandbox Code Playgroud)

主程序

#include <iostream>
#include "node.h"

int main() {

    Node node = new Node("Hello World");

    std::cout << "Node data: " << node.get_data() << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出

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


Run Code Online (Sandbox Code Playgroud)

Adr*_*ica 8

您面临的问题是您正在使用new创建一个节点,但随后尝试将返回的指针分配给非指针Node变量。

这行是问题所在:

Node node = new Node("Hello World");
Run Code Online (Sandbox Code Playgroud)

其作用是首先构造一个模板类型为;的未命名对象。 然后,通过使用指向该新对象的指针来初始化变量,您将构造第二个对象,推导的模板类型为。显示十六进制值的行正确显示了存储在第二个命名变量中的地址值。Nodeconst char *nodeNodeNode*cout Node

您可以通过多种方式解决这个问题。最简单的方法是不使用new运算符:

Node node{ "Hello World" }; // Construct object directly
Run Code Online (Sandbox Code Playgroud)

另一种方法是继续使用该new调用,但然后设置node一个指针:

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;
}
Run Code Online (Sandbox Code Playgroud)

函数 中的第一行代码main实际上是这样做的:

Node node{ new Node("Hello World") };
Run Code Online (Sandbox Code Playgroud)

因此,创建两个节点,其中命名的节点的模板类型为Node<const char*>*。或者,换句话说,您的第一行相当于以下内容,具有显式模板类型:

Node< Node<const char*>* > node = new Node<const char*>("Hello World");
Run Code Online (Sandbox Code Playgroud)

另请注意,=这里的运算符不是赋值而是初始化;这就是调用构造函数的原因。


for*_*818 7

如果没有CTAD(类模板参数推导),main 中的行如下所示:

Node<Node<const char*>*> node = new Node<const char*>("Hello World");
Run Code Online (Sandbox Code Playgroud)

我不确定你真正想要什么,但我确信它不是这个。

打印的地址是 的Node<const char*>*成员的值Node<Node<const char*>*>


请注意,接下来的内容是不好的品味。这是一个笑话。如果您不明白这个笑话,请忘记您已经看过代码。不要在家里做这个。或者在工作中。或者真的任何地方。不是。在c++中。请。好的,让我们一起做。

我从操作代码和字符串文字中删除了一些多余的内容,以避免可能对转换或数组到指针衰减产生混淆。现在,这将产生预期输出42

#include <iostream>

template <typename T>
struct Node {
    T data;
    Node(T data) : data(data) {}
    Node(Node<T>* other) : data(other->data) { delete other; }
};

int main() {
    Node node = new Node(42);
    std::cout << "Node data: " << node.data << std::endl;
}
Run Code Online (Sandbox Code Playgroud)