Ну, я близок к тому, чтобы отказаться от двенадцати лет работы 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: Виртуальные функции деструктора уже добавлены как другие посты и не работают.
Для того, чтобы набрать 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);
}
Добавление PACKAGE в определение класса TStructTreeNode решило проблему
class PACKAGE TStructTreeNode: public TTreeNode
Но все же кажется, что Embarcadero работает беспорядочно, потому что в том же пакете у меня есть другой модуль, в котором динамическое приведение класса TMDTreeNode работает без инструкции PACKAGE.
class TMDTreeNode: public TTreeNode
Ваш код:
((TStructTreeNode*)(Items->Item[i]))->ToggleChecked();
не «доказывает», что Items->Item[i]
это (TStructTreeNode *)
или даже близко. Все, что он говорит, это интерпретировать память в том месте, на которое в данный момент указывает этот указатель, как если бы это было TStructTreeNode
,
Если это не TStructTreeNode
тогда поведение не определено, это означает, что оно может или не может казаться успешным. Даже если это TStructTreeNode, то dynamic_cast<>
потерпит неудачу, если тип данных Items->Item[i]
не указатель на базовый класс TStructTreeNode
, Я надеюсь, что вы этого не ожидаете dynamic_cast<>
будет «расшифровывать» void *
или что-то.
Можете ли вы показать декларацию Item
?