Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
 Аватар для HighPredator
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3

ООП. Динамическое приведение типа от родителя к наследнику

21.08.2015, 14:12. Показов 3446. Ответов 26

Студворк — интернет-сервис помощи студентам
Добрый день, коллеги. Проблема в следующем. Есть два библиотечных класса (xerces).
1) DOMElement
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class DOMElement : public DOMNode
{           
public:         
  virtual   const XMLCh *   getTagName() const = 0;
  virtual   const XMLCh *   getAttribute(const XMLCh *name) const = 0;
  virtual   DOMAttr *   getAttributeNode(const XMLCh *name) const = 0;
  virtual   DOMNodeList *   getElementsByTagName(const XMLCh *name) const = 0;
  virtual   void    setAttribute(const XMLCh *name, const XMLCh *value) = 0;
  virtual   DOMAttr *   setAttributeNode(DOMAttr *newAttr) = 0;
  virtual   DOMAttr *   removeAttributeNode(DOMAttr *oldAttr) = 0;
  virtual   void    removeAttribute(const XMLCh *name) = 0;
  virtual   const XMLCh *   getAttributeNS(const XMLCh *namespaceURI, const XMLCh *localName) const = 0;
  virtual   void    setAttributeNS(const XMLCh *namespaceURI, const XMLCh *qualifiedName, const XMLCh *value) = 0;
  virtual   void    removeAttributeNS(const XMLCh *namespaceURI, const XMLCh *localName) = 0;
  virtual   DOMAttr *   getAttributeNodeNS(const XMLCh *namespaceURI, const XMLCh *localName) const = 0;
  virtual   DOMAttr *   setAttributeNodeNS(DOMAttr *newAttr) = 0;
  virtual   DOMNodeList *   getElementsByTagNameNS(const XMLCh *namespaceURI, const XMLCh *localName) const = 0;
  virtual   bool    hasAttribute(const XMLCh *name) const = 0;
  virtual   bool    hasAttributeNS(const XMLCh *namespaceURI, const XMLCh *localName) const = 0;
  virtual   void    setIdAttribute(const XMLCh* name, bool isId) = 0;
  virtual   void    setIdAttributeNS(const XMLCh* namespaceURI, const XMLCh* localName, bool isId) = 0;
  virtual   void    setIdAttributeNode(const DOMAttr *idAttr, bool isId) = 0;
  virtual   const DOMTypeInfo*  getSchemaTypeInfo() const = 0;
  virtual   DOMElement *    getFirstElementChild() const = 0;
  virtual   DOMElement *    getLastElementChild() const = 0;
  virtual   DOMElement *    getPreviousElementSibling() const = 0;
  virtual   DOMElement *    getNextElementSibling() const = 0;
  virtual   XMLSize_t   getChildElementCount() const = 0;
};

2) DOMNode
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
class DOMNode
{           
public:         
  enum  NodeType {  
    ELEMENT_NODE    = 1,
    ATTRIBUTE_NODE  = 2,
    TEXT_NODE   = 3,
    CDATA_SECTION_NODE  = 4,
    ENTITY_REFERENCE_NODE   = 5,
    ENTITY_NODE = 6,
    PROCESSING_INSTRUCTION_NODE = 7,
    COMMENT_NODE    = 8,
    DOCUMENT_NODE   = 9,
    DOCUMENT_TYPE_NODE  = 10,
    DOCUMENT_FRAGMENT_NODE  = 11,
    NOTATION_NODE   = 12,
  };        
  enum  DocumentPosition {  
    DOCUMENT_POSITION_DISCONNECTED  = 0x01,
    DOCUMENT_POSITION_PRECEDING = 0x02,
    DOCUMENT_POSITION_FOLLOWING = 0x04,
    DOCUMENT_POSITION_CONTAINS  = 0x08,
    DOCUMENT_POSITION_CONTAINED_BY  = 0x10,
    DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC   = 0x20,
  };        
  virtual   const XMLCh *   getNodeName() const = 0;
  virtual   const XMLCh *   getNodeValue() const = 0;
  virtual   NodeType    getNodeType() const = 0;
  virtual   DOMNode *getParentNode() const = 0;
  virtual   DOMNodeList *getChildNodes() const = 0;
  virtual   DOMNode *getFirstChild() const = 0;
  virtual   DOMNode *getLastChild() const = 0;
  virtual   DOMNode *getPreviousSibling() const = 0;
  virtual   DOMNode *getNextSibling() const = 0;
  virtual   DOMNamedNodeMap *getAttributes() const = 0;
  virtual   DOMDocument *getOwnerDocument() const = 0;
  virtual   DOMNode *   cloneNode(bool deep) const = 0;
  virtual   DOMNode *insertBefore(DOMNode *newChild, DOMNode *refChild) = 0;
  virtual   DOMNode *replaceChild(DOMNode *newChild, DOMNode *oldChild) = 0;
  virtual   DOMNode *removeChild(DOMNode *oldChild) = 0;
  virtual   DOMNode *appendChild(DOMNode *newChild) = 0;
  virtual   bool    hasChildNodes() const = 0;
  virtual   void    setNodeValue(const XMLCh *nodeValue) = 0;
  virtual   void    normalize() = 0;
  virtual   bool    isSupported(const XMLCh *feature, const XMLCh *version) const = 0;
  virtual   const XMLCh *   getNamespaceURI() const = 0;
  virtual   const XMLCh *   getPrefix() const = 0;
  virtual   const XMLCh *   getLocalName() const = 0;
  virtual   void    setPrefix(const XMLCh * prefix) = 0;
  virtual   bool    hasAttributes() const = 0;
  virtual   bool    isSameNode(const DOMNode* other) const = 0;
  virtual   bool    isEqualNode(const DOMNode* arg) const = 0;
  virtual   void*   setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler) = 0;
  virtual   void*   getUserData(const XMLCh* key) const = 0;
  virtual   const XMLCh*    getBaseURI() const = 0;
  virtual   short   compareDocumentPosition(const DOMNode* other) const = 0;
  virtual   const XMLCh*    getTextContent() const = 0;
  virtual   void    setTextContent(const XMLCh* textContent) = 0;
  virtual   const XMLCh*    lookupPrefix(const XMLCh* namespaceURI) const = 0;
  virtual   bool    isDefaultNamespace(const XMLCh* namespaceURI) const = 0;
  virtual   const XMLCh*    lookupNamespaceURI(const XMLCh* prefix) const = 0;
  virtual   void*   getFeature(const XMLCh* feature, const XMLCh* version) const = 0;
  virtual   void    release() = 0;
  virtual   void    decRefCount() {}
  virtual   void    incRefCount() {}
};
На основе примеров в сети http://www.yolinux.com/TUTORIALS/XML-Xerces-C.html , http://stackoverflow.com/quest... n-xerces-c сделал кусок парсера xml документа в следующем виде (интересующая часть):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
for(XMLSize_t i = 0; i < childrenNodeCount; ++i)
{
  DOMNode* currentNode = children->item(i);
 
  if ((currentNode->getNodeType() != 0) && (currentNode->getNodeType() == DOMNode::ELEMENT_NODE))
  {
    DOMElement* currentElement = dynamic_cast<xercesc::DOMElement*>(currentNode); // !!!
 
    if (XMLString::equals(currentElement->getTagName(), TAG_SectionHeader))
    {
      // parse this part
    }
 
    if (XMLString::equals(currentElement->getTagName(), TAG_SectionBody))
    {
      // parse this part
    }
  }
}
Теперь собственно суть проблемы: данный код работает идеально под виндой (студийный компиль), но под никсами (xlc++) после выделенной строки валится с SIGILL-ом. Причина оказалась в том, что динамик каст выдал нулевой указатель (исключения не было). Код становится рабочим (но кривым по сути) если динамик каст заменить на static_cast. Три вопроса:
1) Почему работает в первом случае и не работает во втором?
2) Есть ли у таких вещей зависимости от компилятора?
3) Как сделать максимально грамотно?

Спасибо.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.08.2015, 14:12
Ответы с готовыми решениями:

Динамическое приведение типа
всем доброго времени! есть метод в который передается тип object. он может быть любым. в результате необходимо привести его к определенному...

Приведение к типу-наследнику
#include &lt;iostream&gt; class A { }; class B: public A { void foo() const { std::cout &lt;&lt; &quot;some is king of every fish&quot;; } }; int...

Приведение базового класса к наследнику
Допустим, есть такие классы class First { public string fieldFirst; } class Second:First { public string fieldSecond; }Из...

26
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
21.08.2015, 16:05
Студворк — интернет-сервис помощи студентам
HighPredator, Можно было бы попробовать проверить еще написать простенький пример, который создаст объект DOMElementImpl, присвоит указатель на него указателю на DOMNode и попробовать сделать dyn_cast к DOMElement, но я хз насколько это поможет.
1
 Аватар для HighPredator
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
21.08.2015, 16:15  [ТС]
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Короче, я нашел, в чем проблема. Разработчики поставляют эту либу с выключенным rtti. Поэтому касты не работают. Придется работать со статик кастами... https://issues.apache.org/jira/browse/XERCESC-819

Добавлено через 30 секунд
ForEveR, спасибо за помощь.
2
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
21.08.2015, 16:21
HighPredator, Интересно... А для винды почему работает? Там с включенным RTTI? Ну да, раз так и неохота пересобирать либу с включенным rtti стоит юзать static или reinterpret.
0
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
21.08.2015, 16:21
HighPredator, так его можно отключить? Разве можно либу от RTTI отключить? Или они просто ее компилировали без этой опции?
0
 Аватар для HighPredator
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
21.08.2015, 16:28  [ТС]
tnk500, да, можно. Для xlc++ например это ключ -qnortti.

Добавлено через 2 минуты
ForEveR, дело не в том, что я не хочу. Просто эта либа в том виде в котором она есть, уже много лет на боевом железе и мне никто не даст ее пересобрать.

Добавлено через 1 минуту
И по ходу да, виндовая версия уже имеет включенный rtti.
0
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
21.08.2015, 16:28
HighPredator, вот те раз, я думал его поддержка встроена наглухо. Интересно, а на кой ее вообще отключать? Её плюшки не очень требовательны, проблем с производительностью вроде не должна генерировать. Да и со старым кодом (в котором static_cast'ы и использовались) не должна проблем вызывать
0
 Аватар для HighPredator
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
21.08.2015, 16:31  [ТС]
Цитата Сообщение от tnk500 Посмотреть сообщение
Интересно, а на кой ее вообще отключать?
С учетом ее архитектуры, этого вообще имхо нельзя было делать. Ну, как говорится, что имеем, то имеем.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.08.2015, 16:31
Помогаю со студенческими работами здесь

Не могу вернуть подключение классу наследнику php ооп
День добрый.. не могу вернуть подключение классу наследнику.. для дальнейшей работы базы данных.. Раньше программировал процедурной...

Приведение класса родителя к классу потомку java
Наткнулся на такой кусок кода в книге Хорстмана public void paintComponent(Graphics g) { super.paintComponent(g); ...

ООП - изменение переменной родителя
Простой скрипт В корне есть переменная $SERVER_PARAMS{location} = 1; В пакет Components передаю весь хэш %SERVER_PARAMS ...

Динамическое приведение
Добрый день вот код) В низу проблема) #ifndef SHAPE_H #define SHAPE_H class Shape { public: Shape ();

Вывод поста, который содержит id категории, её родителя, родителя родителя
Есть 2 таблицы, первая - категории ( category_id, parent_id и т.д), вторая - посты (post_id, category_id) В общем, в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru