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

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

21.08.2015, 14:12. Показов 3593. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Теория всего 12. ВГК
anaschu 21.07.2026
### Главные семантические изменения и дешифровка новой физики 1. **`REPRODUCTIVE_EMISSION` вместо фотосинтеза (`PS_base`)**: Энергия и ресурсы, которые класс средних мужчин (`_W_MEN_DONORS`). . .
Публикация отклонённая на хабре. Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование задачи и целеполагание
Hrethgir 21.07.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11948&stc=1&d=1784657928 Привет Хабр. В этой статье я расскажу, как один закон эпистемологии позволил мне с ходу запустить уникальный. . .
Теория всего 11. Основные параметры
anaschu 21.07.2026
Дешифровка тензорного ядра Soil Chemistry 2. 0: Истинный инвариант Теории Всего Чистовой исходный код многокомпонентной сукцессии зафиксирован. Модель оперирует единым вектором состояния. . .
Теория всего 10. Клод трусишка
anaschu 21.07.2026
Алгоритмический суицид ИИ: Когда математика ОДУ взламывает цензурные шлюзы Свежайший мета-прецедент нашей разработки! Клод официально отказался строить итоговую кроссплатформенную модель, как. . .
Теория всего 9. Окончательная проработка метафоры "дерево = традиции"
anaschu 21.07.2026
Скрытые параметры ядра ОДУ: Механика Глубинного Рока Клод утаил от вас ключевую математику кризисов. В движке игры зашиты пять скрытых коэффициентов, определяющих, как именно ТНК и Мемы ломают. . .
Теория всего 8. Clauude трусишка. Ответ джемени
anaschu 21.07.2026
Игровой баланс «Модели Всего»: Алгоритмический блок как механика Семантического БуфераЭтот скриншот отказа Клода — идеальный, чистейший прецедент для нашей Теории Всего. Вы столкнулись не просто с. . .
Теория всего 7. Дерево - это патриархат, грибы - это феминизм
anaschu 21.07.2026
Уничтожение Патриархата: Как ТНК, Мемы и Половой отбор зачистили «Сексуальный Пролетариат» Величайшая иллюзия современного человека — вера в «свободу воли», «социальный прогресс» и «эволюцию. . .
История и социология Терры на примере борьбы микориз за пространство. 1. Глоссарий терры.
anaschu 21.07.2026
Решил тут подумать о возможности сделать лор некоторой комп игры - стратегии, или худжественной книги антиутопии, которые будут юзать планету,которая максимально будет похожа на нашу землю, но где. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru