C ++ Builder — более ошибочное поведение на C ++ Builder. xe2: DYNAMIC_CAST всегда возвращает NULL.

Ну, я близок к тому, чтобы отказаться от двенадцати лет работы Delphi и C ++ из-за Embarcadero. Никогда не вижу такой проблемной IDE.

На этот раз проблема в том, что dynamic_cast всегда возвращает NULL.

В том же модуле я вывел два класса:

class TStructTreeNode: public TTreeNode
class PACKAGE TStructTreeView : public TTreeView

Приведение к TStructTreeView работает нормально:

TStructTreeView* tv = dynamic_cast<TStructTreeView*>( AOwner->Owner );

Но приведение к TStructTreeNode ВСЕГДА ВОЗВРАЩАЕТСЯ НУЛЬ:

TStructTreeNode* snode = dynamic_cast<TStructTreeNode*>(Items->Item[i]);

Обратите внимание, что Items-> Item [i] действительно TStructTreeNode, потому что следующий код работает нормально:

((TStructTreeNode*)(Items->Item[i]))->ToggleChecked();

Узел создан следующим образом:

TStructTreeNode* snode = new TStructTreeNode(Items,UniqueID);
TTreeNode* node = Items->AddNode(snode,Relative,S,Ptr,Method);

В этом же пакете у меня есть другой компонент с классами TMDTreeNode и TMDTreeView, полученными таким же образом, в этом модуле все dynamic_casts работает.

Любой свет можно только приветствовать.

PS: Виртуальные функции деструктора уже добавлены как другие посты и не работают.

0

Решение

Для того, чтобы набрать TTreeNode указатель на TStructTreeNode указатель с dynamic_castВы должны создать настоящий TStructTreeNode экземпляр, чтобы удовлетворить бросок. Если вы используете общий TTreeNodes методы, как Add()затем переопределите виртуальный CreateNode() способ рассказать TTreeView создавать TStructTreeNode случаи, а не TTreeNode экземпляров. Например:

class PACKAGE TStructTreeView : public TTreeView
{
protected:
virtual TTreeNode* __fastcall CreateNode();
};

TTreeNode* __fastcall TStructTreeView::CreateNode()
{
return new TStructTreeNode(Items);
}
0

Другие решения

Добавление PACKAGE в определение класса TStructTreeNode решило проблему

class PACKAGE TStructTreeNode: public TTreeNode

Но все же кажется, что Embarcadero работает беспорядочно, потому что в том же пакете у меня есть другой модуль, в котором динамическое приведение класса TMDTreeNode работает без инструкции PACKAGE.

class TMDTreeNode: public TTreeNode
0

Ваш код:

((TStructTreeNode*)(Items->Item[i]))->ToggleChecked();

не «доказывает», что Items->Item[i] это (TStructTreeNode *)или даже близко. Все, что он говорит, это интерпретировать память в том месте, на которое в данный момент указывает этот указатель, как если бы это было TStructTreeNode,

Если это не TStructTreeNode тогда поведение не определено, это означает, что оно может или не может казаться успешным. Даже если это TStructTreeNode, то dynamic_cast<> потерпит неудачу, если тип данных Items->Item[i] не указатель на базовый класс TStructTreeNode, Я надеюсь, что вы этого не ожидаете dynamic_cast<> будет «расшифровывать» void * или что-то.

Можете ли вы показать декларацию Item ?

0