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

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

21.08.2015, 14:12. Показов 3728. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
Генератор паролей (вариант №2)
Maks 30.10.2026
Обновленная версия ранее созданной обработки. Добавлены следующие реквизиты типа Булево: - Буквы; - Цифры; - Символы. Изменена логика команды "Сгенерировать" и процедуры "ПриОткрытии":. . .
Генератор паролей (вариант №1)
Maks 29.10.2026
Реализация из решения ниже выполнена исключительно по моей инициативе, дабы облегчить себе работу в создании паролей для администрируемых мною сервисов и пользователей. Самым главным критерием для. . .
Установка ChatGPT (Codex) на Windows без использования Microsoft Store
Fabien159 28.10.2026
Здравствуйте всем читающим! Опишу процесс установки ChatGPT (Codex) на Windows, если по каким-то причинам у вас не получается устанавить его через Microsoft Store. И так: 1. Скачиваем с. . .
Программное добавление префикса в нумерацию документов
Maks 27.10.2026
Реализация из решения ниже выполнена в самописной конфигурации на БСП (помощь начинающему коллеге). Задача: Программно добавить префикс в нумерацию документов. Решение: В модуле объекта. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru