Проверка RTTI

У меня есть следующие классы и методы:

//Base class
class Node {
    public:
        virtual ~Node() {};
        Node() {};
    private:
        // Private things for my implementation.
};

class Element : public Node {
    public:
        // Returns the name of the element.
        const xml::String &name() const {
            return eleName;
        }

        static bool is_Element(const Node *base) {
            Element *p = NULL;
            p = dynamic_cast<Element*>(base);
            return (p!=NULL);
        }

        static const Element *to_Element(const Node *base) {
            return dynamic_cast<Element*>(base);   
        }

    private:
        s_namespace eleNamespace;
        xml::String &eleName;
        // Private things for my implementation.
};

Здесь, когда я выполняю динамическое приведение, выдается следующая ошибка компиляции. Как это исправить? Один из способов — просто удалить const параметров. Но я не думаю, что это правильный метод.

oops.cpp: в статической функции-члене 'static bool xml::Element::is_Element(const xml::Node*)': oops.cpp:208:44: ошибка: не может dynamic_cast 'base' (типа 'const class xml ::Node*') для ввода 'class xml::Element*' (преобразование отбрасывает константность) oops.cpp: в статической функции-члене 'static const xml::Element* xml::Element::to_Element(const xml:: Node*)': oops.cpp:213:47: ошибка: невозможно dynamic_cast 'base' (типа 'const class xml::Node*') для типа 'class xml::Element*' (преобразование отбрасывает константность)


person footy    schedule 03.03.2013    source источник
comment
Ошибка говорит сама за себя: conversion casts away constness.   -  person chris    schedule 03.03.2013
comment
@Крис, да. Итак, как я должен относиться к этому по-другому?   -  person footy    schedule 03.03.2013
comment
Передайте его const Element*. Потому что приведение его к Element* отбрасывает константность.   -  person Drew Dormann    schedule 03.03.2013
comment
@footy Использование dynamic_cast для определения динамического типа объекта обычно является признаком плохого дизайна. Зачем вам знать, является ли ваш Node Element? Вы должны иметь возможность использовать Element, как если бы это был Node.   -  person Joseph Mansfield    schedule 03.03.2013
comment
Это не имеет никакого отношения к проблеме, но is_Element должно возвращать p != NULL, а не base != NULL.   -  person Pete Becker    schedule 03.03.2013
comment
@Flexo Хм .. Наверное, нет, так как ответ Александра - это то, что я искал.   -  person footy    schedule 03.03.2013
comment
@PeteBecker Спасибо! Это была опечатка в вопросе. Не преднамеренно. Я починил это.   -  person footy    schedule 03.03.2013


Ответы (2)


Вместо этого используйте dynamic_cast<const Element*>.

Вы также можете сделать свой класс константно-правильным, реализовав две разные функции для константного аргумента и неконстантного аргумента:

    static const Element *to_Element(const Node *base) {
        return dynamic_cast<const Element*>(base);   
    }

    static Element *to_Element(Node *base) {
        return dynamic_cast<Element*>(base);   
    }

Итак, если у вызывающего абонента есть неконстантный Node, он, вероятно, также хочет неконстантный Element, и теперь он может его получить...

person Alexander Tobias Bockstaller    schedule 03.03.2013
comment
Это именно то, чего я хотел добиться! Ты читаешь мои мысли. Спасибо :) - person footy; 03.03.2013
comment
Попытка понять здесь: в приведенном выше решении функция to_Element() перегружена? Но у меня были функции чтения, которые не перегружались просто из-за того, что аргументы были константными в одном и неконстантными в другом. Как работает этот конкретный раствор. работай? - person goldenmean; 06.03.2013

Попробуй это:

static bool is_Element(const Node *base) {
    const Element *p = NULL; // Add a const keyword here
    p = dynamic_cast<const Element*>(base); // Add a const keyword here
    return (base!=NULL);
}

И то же самое для to_Element

person masoud    schedule 03.03.2013
comment
p – это Element*, которое не может содержать Element const*. - person Nawaz; 03.03.2013