我想使用TOwnedCollection / TCollectionItem实现一个集合或列表。我需要一个具有多态性的类的持久列表(从FileStream加载和创建)。
这是到目前为止我的代码的一部分,但是我没有成功地创建派生类TGenerator,而不是它的父类TPowerComponent,并将它添加到集合中。
//-------------------------------------------------------------------------------------
class TPCCollection : public TOwnedCollection
{
typedef TOwnedCollection inherited;
private:
TPowerComponent* __fastcall GetPowerComponent(int Index);
void __fastcall SetPowerComponent(int Index, TPowerComponent *Value);
public:
__fastcall TPCCollection(TPersistent *Owner);
HIDESBASE TPowerComponent* __fastcall Add(void);
HIDESBASE TPowerComponent* __fastcall Insert(int Index);
__property TPowerComponent* PCCollection[int Index] = {read=GetPowerComponent, write=SetPowerComponent};
};
//-------------------------------------------------------------------------------------
class TPowerComponent : public TCollectionItem
{
typedef TCollectionItem inherited;
public :
int X, Y, Rotation;
PowSymbType HisType;
__fastcall TPowerComponent(TCollection *Collection, PowSymbType AType );
void __fastcall Assign(TPersistent *Source);
virtual void __fastcall Paint(TCanvas * Canvas);
};
//-------------------------------------------------------------------------------------
class TGenerator : public TPowerComponent
{
typedef TPowerComponent inherited;
public :
double PG, Qgmin, Qgmax, Vsch;
__fastcall TGenerator(TCollection *Collection, PowSymbType AType );
void __fastcall Assign(TPersistent *Source);
virtual void __fastcall Paint(TCanvas * Canvas);
};
//-------------------------------------------------------------------------------------
// implementation
//-------------------------------------------------------------------------------------
// TPCCOllection
//-------------------------------------------------------------------------------------
__fastcall TPCCollection::TPCCollection(TPersistent *Owner)
: TOwnedCollection(Owner, __classid(TPowerComponent))
{
}
//-------------------------------------------------------------------------------------
TPowerComponent* __fastcall TPCCollection::Add()
{
return static_cast<TPowerComponent>(inherited::Add());
}
//-------------------------------------------------------------------------------------
TPowerComponent* __fastcall TPCCollection::Insert(int Index)
{
return static_cast<TPowerComponent>(inherited::Insert(Index));
}
//-------------------------------------------------------------------------------------
TPowerComponent* __fastcall TPCCollection::GetPowerComponent(int Index)
{
return static_cast<TPowerComponent>(inherited::GetItem(Index));
}
//-------------------------------------------------------------------------------------
void __fastcall TPCCollection::SetPowerComponent(int Index, TPowerComponent *Value)
{
inherited::SetItem(Index, Value);
}
//-------------------------------------------------------------------------------------
// TPowerComponent
//-------------------------------------------------------------------------------------
__fastcall TPowerComponent::TPowerComponent(TCollection *Collection, PowSymbType AType )
: TCollectionItem(Collection)
{
HisType=AType;
Rotation=0;
}
//-------------------------------------------------------------------------------------
void __fastcall TPowerComponent::Assign(TPersistent *Source)
{
TPowerComponent *Src = dynamic_cast<TPowerComponent>(Source);
if( Src )
{
// copy members from Src...
}
else inherited::Assign(Source);
}
//-------------------------------------------------------------------------------------
// se dessine
void __fastcall TPowerComponent::Paint(TCanvas * Canvas)
{
...
}
//-------------------------------------------------------------------------------------
// TGenerator
//-------------------------------------------------------------------------------------
__fastcall TGenerator::TGenerator(TCollection *Collection, PowSymbType AType )
:TPowerComponent( Collection, AType )
{
PG=0; Qgmin=0; Qgmax=0; Vsch=1.0; Con=-1;
}
//-------------------------------------------------------------------------------------
void __fastcall TGenerator::Assign(TPersistent *Source)
{
TGenerator *Src = dynamic_cast<TGenerator>(Source);
if( Src )
{
// copy members from Src...
}
else inherited::Assign(Source);
}
//-------------------------------------------------------------------------------------
// Usage
TPCCollection * NetWork = new TPCCollection(this);
// Usage to Access all the collection
for( int i=0; i< NetWork->Count; i++)
{
((TPowerComponent*)(NetWork->Items[i]))->Paint(Canvas);
}要添加TGenerator而不是TPowerComponent,我使用:
TGenerator * Gen=new TGenerator( NetWork, Generator);创建TCollectionItem子级时会自动将其自身添加到TCollection中
这里的问题是,我们不能将创建项目的过程与将其添加到集合中的过程分开。
例如,当我需要另一个可以包含第一个集合列表中的某些项的列表时,SelectedComponents可以包含NetWork集合中的一个或某些项,而无需重新创建它们。
这可以通过以下命令完成
std::list<TPowerComponent*> SelectedComponents;但是我不能使用FileStream / persistent list来写/读它们。我需要将它们放在TCollection中,但不需要重新创建它们。
多么?
发布于 2018-01-05 04:41:06
RTL针对TCollection对象的原生DFM流只部分支持多态TCollectionItem类。
您可以在代码中将多态TCollectionItem对象添加到TCollection中(在运行时,以及在设计时借助自定义编辑器),只要它们都派生自传递给TCollection构造函数的公共基类。这样的集合甚至可以按原样保存到DFM。
但是,当加载回DFM时,本地流将强制从DFM读取的所有集合项使用您传递给TCollection构造函数的任何TCollectionItem类类型。因此,多态类不能在本地加载。
覆盖该行为的唯一方法是禁用集合的本机流式处理(使TCollection属性为非published,或者至少将其标记为stored=false),然后手动流式处理收集项。
让您的主组件(或任何拥有该集合的TPersistent类)覆盖虚拟DefineProperties()方法,以调用TFiler.DefineProperty()来注册用于流式传输集合项的自定义读/写方法。要支持多态类,必须在写入属性值之前将每个项的ClassName写入DFM,然后读回名称,以便在读取属性值之前知道要实例化哪个类。
https://stackoverflow.com/questions/48011100
复制相似问题