Почему шаблон 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;
        }
};

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

выход

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


Код, который вы показываете, и вывод, который вы показываете, не совпадают. Ваш код даже не скомпилируется Пожалуйста, предоставьте минимальный воспроизводимый пример

ChrisMM 22.02.2023 18:12

как вы думаете, что такое T? и очень связано с этим, почему вы используете new?

463035818_is_not_a_number 22.02.2023 18:12

@ChrisMM Что вы имеете в виду, что вывод не совпадает? Я обновил вопрос.

Gabriel Gavrilov 22.02.2023 18:13

вам удалось скомпилировать Node x = new Node, +1 за это. Это интересный случай максимальной путаницы, вызванной бессмысленным использованием new.

463035818_is_not_a_number 22.02.2023 18:14

Текст в нем отличается от вывода. Таким образом, они не могут быть связаны.

ChrisMM 22.02.2023 18:14

@ChrisMM компилируется, есть два разных экземпляра Node

463035818_is_not_a_number 22.02.2023 18:15

@ 463035818_is_not_a_number, ты прав. Внимательнее надо было читать. Однако вывод по-прежнему не совпадает с кодом.

ChrisMM 22.02.2023 18:15

@ 463035818_is_not_a_number Вы правы. Удаление нового исправило это. Когда я должен использовать new при запуске класса? (Я все еще изучаю C++, так что, пожалуйста, потерпите меня).

Gabriel Gavrilov 22.02.2023 18:16

Первая строка кода OP в их main эффективно делает это: Node node{ new Node("Hello World") };. Таким образом, создаются два узла, один из которых имеет тип шаблона Node*.

Adrian Mole 22.02.2023 18:16

Ммм ... Я никогда не думал, что вывод аргумента шаблона класса может иметь эту конкретную ошибку. C++ и его новые свойства становятся «лучше» с каждым днем.

StoryTeller - Unslander Monica 22.02.2023 18:18

Я не думаю, что дубликат подходит. В этом коде происходит гораздо больше. И адрес не из печати массива. Проголосовать за открытие

463035818_is_not_a_number 22.02.2023 18:18

Как вы думаете, какое значение имеет T для node? std::string? const char[12]? На самом деле у вас есть Node<Node<const char*>*>.

Nathan Pierson 22.02.2023 18:19

Вау, эта строка Node x = new Node очень запутанная, я думаю, она заслуживает фактического ответа.

pptaszni 22.02.2023 18:21

«Эта строка» — результат того, что кто-то, кто знает C# или Java, пытается изучить C++ и предполагает, что C++ работает так же. Это не так.

Sam Varshavchik 22.02.2023 18:29

Самое смешное, что можно написать еще один конструктор и руководство по дедукции, которое заставит Node x = new Node делать «правильные вещи». Наконец-то можно написать это на C++. Ууууу. Я не думаю, что это то, что они имели в виду, когда представляли ctad :D

463035818_is_not_a_number 22.02.2023 18:34

"когда я должен использовать новый" - никогда. (Вы будете сейчас, когда вам нужно, но никогда не является хорошим приближением)

463035818_is_not_a_number 22.02.2023 19:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
16
101
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Без CTAD строка в main выглядит так:

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

Я не уверен, что вы на самом деле хотели, но я уверен, что это не это.

Напечатанный адрес является значением Node<const char*>* члена Node<Node<const char*>*>.

Ответ принят как подходящий

Проблема, с которой вы столкнулись, заключается в том, что вы используете new для создания узла, но затем пытаетесь присвоить указатель, возвращаемый переменной Node без указателя.

Эта строка является проблемой:

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

Что это делает, так это сначала создает безымянный объект Node с типом шаблона const char *; затем, используя указатель на этот новый объект для инициализации вашей переменной node, вы создаете второй объект Node с выведенным типом шаблона Node*. Строки cout, показывающие шестнадцатеричные значения, правильно отображают значение адреса, хранящееся во второй переменной с именем Node.

Вы можете обойти это несколькими способами. Проще всего не использовать оператор 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*>*. Или, другими словами, ваша первая строка эквивалентна следующей с явными типами шаблонов:

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

Также обратите внимание, что оператор = здесь не присваивание, а инициализация; вот почему вызывается конструктор.

Спасибо, что помогли мне решить проблему и объяснили мне, что я делаю неправильно!

Gabriel Gavrilov 22.02.2023 18:29

Другие вопросы по теме