C ++ TStringList AddObject

时间:2018-05-09 16:01:35

标签: c++builder

在C ++ Builder中,我编写了一个用于存储float的简单类。 接下来,我尝试使用AddObject的{​​{1}}。

唉,编译器给出了2个错误,指向TStringList的行:

  

无法将'TFloatNum'转换为'TObject *'

     

参数'AObject'中的类型不匹配(想要'TObject *',得到'TFloatNum')

我做错了什么?

AddObject

1 个答案:

答案 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::vectorstd::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]);
...