AddObject()
ожидает указатель TObject*
, а не экземпляр объекта TFloatNum
. TFloatNum
не является производным от TObject
, и вы все равно даже не сохраняете указатель.
Вам необходимо динамически распределить объект TFloatNum
, чтобы правильно его хранить и юридически (1) .
Если вы не извлекаете TFloatNum
из TObject
, вам нужно будет привести тип к полученному указателю (обратите внимание - это будет работать только на не-ARC платформах - Windows и OSX - поскольку ARC требует фактического TObject
экземпляры объектов на основе):
void __fastcall TForm1::btnAddClick(TObject *Sender)
{
TFloatNum *G = new TFloatNum;
G->N = 75.5;
StringList1->AddObject("a", reinterpret_cast<TObject*>(G));
}
Затем, чтобы получить его позже:
TFloatNum *G = reinterpret_cast<TFloatNum*>(StringList1->Objects[SomeIndex]);
...
И не забудьте delete
объект объекта, когда вы закончите с его использованием:
delete G;
В качестве альтернативы, выведите TFloatNum
из TObject
, тогда вам не нужно приведение типа при передаче указателя TFloatNum*
на AddObject()
(2) :
class TFloatNum : public TObject {
public:
float N;
};
void __fastcall TForm1::btnAddClick(TObject *Sender)
{
TFloatNum *G = new TFloatNum;
G->N = 75.5;
StringList1->AddObject("a", G);
}
TFloatNum *G = static_cast<TFloatNum*>(StringList1->Objects[SomeIndex]);
...
delete G;
(1) : размер float
составляет 32 бита. Указатель имеет размер 32 или 64 бита, в зависимости от того, компилируете ли вы для 32-битных или 64-битных систем. Вы могли бы воспользоваться этим фактом и поместить объект TFloatNum
непосредственно в сам сохраненный указатель TObject*
без динамического выделения объекта TFloatNum
(это работает только на не-ARC платформах, когда sizeof(TFloatNum) <= sizeof(void*)
):
class TFloatNum {
public:
float N;
};
void __fastcall TForm1::btnAddClick(TObject *Sender)
{
TObject *obj = NULL;
TFloatNum &G = reinterpret_cast<TFloatNum&>(obj);
G.N = 75.5;
StringList1->AddObject("a", obj);
}
TObject *obj = StringList1->Objects[SomeIndex];
TFloatNum &G = reinterpret_cast<TFloatNum&>(obj);
...
(2) : Если вы используете относительно актуальную версию C ++ Builder, TStringList
имеет свойство OwnsObjects
, которое можно установить на true
, чтобы TStringList
бесплатные TObject
объекты на основе автоматически для вас.
Как уже говорилось, лучшим решением будет не хранить TFloatNum
объектов непосредственно в TStringList
таким образом для начала. Храните их в более подходящем контейнере C ++, таком как std::vector
или std::list
. Затем, если по какой-либо причине вам все еще нужен TStringList
, вы можете хранить указатели (std::vector
) или TFloatNum*
указатели (std::list
) в TStringList
, чтобы помочь вам вернуться к TFloatNum
объектам, когда необходимо.
Использование std::vector<TFloatNum>
:
class TFloatNum {
public:
float N;
};
void __fastcall TForm1::btnAddClick(TObject *Sender)
{
TFloatNum G;
G.N = 75.5;
SomeStdVector.push_back(G);
StringList1->AddObject("a", reinterpret_cast<TObject*>(SomeStdVector.size()-1));
}
size_t FloatNumIndex = reinterpret_cast<size_t>(StringList1->Objects[SomeIndex]);
TFloatNum &G = SomeStdVector[FloatNumIndex];
...
Использование std::list<TFloatNum>
:
class TFloatNum {
public:
float N;
};
void __fastcall TForm1::btnAddClick(TObject *Sender)
{
TFloatNum G;
G.N = 75.5;
SomeStdList.push_back(G);
StringList1->AddObject("a", reinterpret_cast<TObject*>(&SomeStdList.back()));
}
TFloatNum *G = reinterpret_cast<TFloatNum*>(StringList1->Objects[SomeIndex]);
...