Как возможно преобразование из одного класса в другой? - PullRequest
2 голосов
/ 27 мая 2019

Я изучаю BST в структурах данных. В моем учебнике я обнаружил код, который не могу понять.

Я упростил это так:

Tree должно быть бинарным деревом поиска.

Node - это вложенная структура в Tree.

Element используется для хранения данных в узле. (Все они изначально должны быть классом шаблона и изначально узел должен также хранить ключ и т. д. Однако в этом случае я опускаю эти детали.)

#include <iostream>

class Element {

};

class Tree {
   public:
    struct Node {
        Element *element;
    };

    Node *root;
    Element* find() {
        Node *tmp = root;
        return (Element *) tmp; // this line
    }
};

int main() {
    Tree t;
    std::cout << t.find() << '\n';
    return 0;
}

В строке 16 (с комментариями), какова функция (Элемент *)? Я предполагаю, что это преобразование, но как возможно преобразование между двумя различными классами? (если мое предположение верно)

1 Ответ

3 голосов
/ 27 мая 2019

В строке 16 (с комментариями), какова функция (Элемент *)?

Полагаю, это преобразование

Это верно.Это явное преобразование;также называется приведением в стиле C.

но как возможно преобразование между двумя различными классами?

Преобразование между двумя классами возможно в двух случаях: один класс имеетконструктор преобразования или другой имеет оператор преобразования.

Node и Element не имеют ни конструкторов преобразования, ни операторов преобразования, поэтому они не могут быть преобразованы друг в друга.Однако показанная программа не конвертирует между классами.Он преобразует между указателями в классы.

Приведение в стиле C выполняет одно или сочетание статического приведения, const-приведения и переинтерпретации в зависимости от типов источника и цели.Для указателей на несвязанные классы не существует допустимого статического приведения, поэтому выполняется переинтерпретация.

Переинтерпретация указателя на несвязанный тип приводит к указателю, который имеет только ограниченное использование.Вы можете сравнить его равенство с другим указателем или преобразовать его обратно в правильный тип, но косвенный такой переинтерпретированный указатель имеет неопределенное поведение, за исключением нескольких случаев.Это не один из исключительных случаев, поэтому мы можем сделать вывод, что «функция» приведения в том, чтобы сделать результат в основном бесполезным.


PS Есть еще одна проблема.t.root никогда не инициализировалось, поэтому оно имеет неопределенное значение, поэтому Node *tmp = root считывает неопределенное значение, поэтому поведение программы не определено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...