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

pkln4tw6  于 2023-03-05  发布在  其他
关注(0)|答案(2)|浏览(137)

我有一个简单的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;
        }
};

主.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;
}

输出

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
xn1cxnb4

xn1cxnb41#

您所面临的问题是,您正在使用new创建一个节点,但随后试图将返回的*指针赋给一个非指针Node变量。
这一行是问题所在:

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

它首先构造一个模板类型为const char *的 * 未命名 * Node对象;然后,通过使用指向该新对象的 * 指针 * 初始化node变量,构造第二个Node对象,推导出的模板类型为Node*cout行显示十六进制值,正确显示了存储在第二个 namedNode变量中的地址值。
你可以用几种方法来解决这个问题,最简单的方法是不使用new操作符:

Node node{ "Hello World" }; // Construct object directly

另一种方法是继续使用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;
}
  • 您的 * main函数中的第一行代码实际上是这样做的:
Node node{ new Node("Hello World") };

这样就创建了两个节点,其中一个节点的模板类型为Node<const char*>*。或者,换句话说,第一行代码相当于下面的代码,模板类型为 explicit

Node< Node<const char*>* > node = new Node<const char*>("Hello World");

还要注意,这里的=操作符 * 不是 * 赋值,而是初始化;这就是调用构造函数的原因。

bjg7j2ky

bjg7j2ky2#

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

Node<Node<const char*>*> node = new Node<const char*>("Hello World");

我不知道你到底想要什么,但我肯定不是这个。
打印的地址是Node<Node<const char*>*>Node<const char*>*成员的值。
请注意,接下来的是不好的品味。这是一个笑话。如果你不明白这个笑话,忘记你已经看到了代码。不要这样做,在家里。或在工作中。或真的任何地方。不。在c++。请。好吧,让我们这样做。
我从OP代码中删除了一些粗糙的地方,也删除了字符串文字,以避免转换或数组到指针衰减时可能出现的混淆。现在,这将产生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;
}

相关问题