在C ++ Builder中,我编写了一个用于存储float的简单类。
接下来,我尝试使用AddObject
的{{1}}。
唉,编译器给出了2个错误,指向TStringList
的行:
无法将'TFloatNum'转换为'TObject *'
参数'AObject'中的类型不匹配(想要'TObject *',得到'TFloatNum')
我做错了什么?
AddObject
答案 0 :(得分:1)
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)< / SUP>:
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
对象(这仅适用于非{ - sizeof(TFloatNum) <= sizeof(void*)
)时的-ARC平台:
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]);
...