![]() |
Verwenden von property in C++ Builder
Moin,
ich brech' mir gerade einen ab, eine TObjectlist im Builder 6 zu definieren.
Delphi-Quellcode:
Die Stelle mit dem "X" wird vom Compiler angemeckert, Meldung steht darunter.
class TParaLine : public TObject
{ __published: TTntEdit *ParaLineEdit; TTntLabel *ParaLineLabel; TTntLabel *UnitLabel; TTntComboBox *Material; TTntComboBox *FlewRate; TTntButton *Get_h; }; class TParas : public TObjectList { private: TParaLine GetItem(int *index); void SetItem(int *index, TParaLine *Line); __published: int Add(TParaLine *ParaLine); __property TParaLine Items[int Id]"X" = {read=GetItem, write=SetItem}; /* Compiler "X": E2459 VCL style classes must be constructed using operator new*/ }; Kommt mir komisch vor, denn die property items bringt die Vorfahrenklasse doch schon mit... Ich habe gesehen, daß man bei einer Frage nach VCL-topics in den C-Foren erstmal eine Grundsatzdiskussion über das Erlaubt-/Verbotensein der VCL-Verwendung ertragen muß, stelle die Frage lieber hier. Grüße, Messie |
Re: Verwenden von property in C++ Builder
Code:
Wenn du in C++ eine Klasse hast kannst du schreiben
TParaLine* GetItem(int index);
void SetItem(int index, TParaLine *Line); __published: int Add(TParaLine *ParaLine); __property TParaLine* Items[int Id]"X" = {read=GetItem, write=SetItem}; // "*" ist wichtig
Code:
Erstere Variante ist bei VCL-Klassen nicht erlaubt.
TMyClass t; Klassenvariable wird definiert UND Klasse erzeugt
//oder TMyClass *p; Zeiger auf Klasse p = new TMyClass; Erzeugen Außerdem mußt du ja hier bei deinem Property Items eh einen Zieger zurückgeben und nicht die gesamte Klasse ;) Hoffe, es war halbwegs verständlich :gruebel: Edit: Hab grad noch was gesehen und korrigiert: int = integer , int* = ^integer. Also nicht GetItem(int *), du wirst kaum einen Zeiger auf ein Int übergeben wollen. Gäbe aber sicher schöne Exceptions :) |
Re: Verwenden von property in C++ Builder
Zitat:
ist schon etwas ungewohnt, die Sternchen an die richtige Stelle zu setzen, mache halt sonst nur Delphi.. Zitat:
Hänge leider gleich an der nächsten Stelle: Das Erzeugen und Füllen der Objectlist mache in einer anderen Unit mit
Delphi-Quellcode:
Wenn ich die Zeile weglasse, in der Test erzeugt wird, ist der Linker zwar still, im Betrieb bekomme ich dann natürlich eine Zugriffsverletzung. Mir ist aber nicht klar, wo der Zusammenhang zu GetItem und SetItem beim Erzeugen ist.
TParas *Test;
Test = new TParas; Test->Add(new TParaLine); /*Linker meckert: [Linker Error] Unresolved external '__fastcall TParas::GetItem(int)' referenced from (...).OBJ [Linker Error] Unresolved external '__fastcall TParas::SetItem(int, TParaLine *)' referenced from (...).OBJ */ Grüße, Messie |
Re: Verwenden von property in C++ Builder
Auf Anhieb sehe ich den Fehler jetzt auch nicht. Falls du dich bis heut abend gedulden kannst, poste ich dir mal ne Klasse für ne getypte Liste. Hab den BCB (und meine Sourcen) nur zuhause. Auf Arbeit muß ich Delphi...
Zitat:
Ich würde dir im übrigen empfehlen, mal einen Blick auf die STL Container-Klassen zu werfen. Mit vector, deque oder aber list läßt sich sowas viiiieeel einfacher und effektiver realisieren als mit VCL-TList u.ä. Und wenn du deine Liste nicht unbedingt an eine VCL-Funktion übergeben mußt, die diesen Typ verlangt, solltest du den Weg über die STL auf jeden Fall vorziehen.
Code:
vector<TParaLine *> paras;
//... paras.push_back(new TParaLine); //... //Zugriff z.B. über paras[i] |
Re: Verwenden von property in C++ Builder
Zitat:
Ich hab' zum letzten mal vor über 10 Jahren mit C zu tun gehabt - da bin ich nie richtig reingekommen. Ist schon klar, das es mehr Freiheiten bietet aber das bedeutet auch daß man mehr wissen muß. Und für mein Projekt (Modifizieren eines kleinen Programms mit VCL-Komponenten) lohnt sich der tiefere Einstieg erstmal nicht. In meinem Bereich wird auch eher LabView immer wichtiger :kotz: Ich warte also lieber bis heute abend... Grüße, Messie |
Re: Verwenden von property in C++ Builder
Uh, sorry :oops: Jetzt fällt mir glatt ein was ich vergessen hab.... Heut abend denk ich dran...
|
Re: Verwenden von property in C++ Builder
Super.
Ich habe auch noch nicht weiter recherchiert weil ich gegen meinen Rechner kämpfe. Habe den ganzen vormittag gebraucht um die Elkos am Spannungsregler auszutauschen - auch was Schönes. Scheint aber jetzt zu laufen, CPU-Temperatur liegt 10 Grad unter dem Wert von gestern... Grüße, Messie |
Re: Verwenden von property in C++ Builder
Soooo. Hab zwar nicht genau das gefunden, was ich posten wollte, aber etwas ähnliches. Erstmal der Source. Ist schon paar Jahre alt, nicht wirklich optimal, sollte aber das Prinzip zeigen.
Die Liste selbst ist allerdings nicht von TObjectList abgeleitet, wie man sieht. Hab noch paar Kommentare eingefügt...
Code:
// in .h
//Die Listenelemente sind von dieser Klasse class TServer { public: AnsiString asURL; AnsiString asLocation; __fastcall TServer(); __fastcall TServer(AnsiString asDesc); }; //--------------------------------------------------------------------------- class TServerList //die Listeklasse als solches... { private: TList *pList; protected: //darf man: der Funktionsrumpf direkt in der Definition, da es keine wirkliche Trennung //zwischen interface und implementation gibt, wie in Pascal int __fastcall GetCount() {return pList->Count;}; public: __fastcall TServerList(); //Konstruktor __fastcall ~TServerList(); //Destruktor TServer *GetItem(int iIndex); //Die Methoden entsprechen denen der TList Klasee der VCL, man könnte noch mehr //implemtieren, wie Exchange oder so, hab ich aber nicht gebraucht. int __fastcall Add(TServer *pSite); void __fastcall Delete(int iIndex); void __fastcall Clear(); int __fastcall IndexOf(AnsiString asSearch); int __fastcall Load(); int __fastcall Save(); __property int Count = {read = GetCount}; __property TServer *Item[int iIndex] = {read = GetItem}; };
Code:
Ich hoffe es nützt was. Wenn nicht, frag ruhig. Wenns nötig auch per PM
//in .cpp
__fastcall TServer::TServer() { asURL = ""; asLocation = ""; } //--------------------------------------------------------------------------- __fastcall TServer::TServer(AnsiString asDesc) { int iPos = asDesc.Pos(";"); if(iPos == 0) { asURL = asDesc; asLocation = "???"; } else { asURL = asDesc.SubString(1, iPos - 1); asLocation = asDesc.SubString(iPos + 1, asDesc.Length() - 1); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- __fastcall TServerList::TServerList() { pList = new TList; } //--------------------------------------------------------------------------- __fastcall TServerList::~TServerList() { if(pList) { for(int i = pList->Count - 1; i >= 0 ; i--) { //Ein Type-casting. TList->Items gibt TObject* (also ein Zeiger auf TObject) zurück, //wir brauchen für die Freigabe aber TServer* delete (TServer *)(pList->Items[i]); pList->Delete(i); } delete pList; pList = NULL; } } //--------------------------------------------------------------------------- int __fastcall TServerList::Add(TServer *pSite) { return pList->Add(pSite); } //--------------------------------------------------------------------------- void __fastcall TServerList::Delete(int iIndex) { if(iIndex >= pList->Count) return; delete (TServer *)(pList->Items[iIndex]); pList->Delete(iIndex); } //--------------------------------------------------------------------------- void __fastcall TServerList::Clear() { //Liste von hinten löschen for(int i = pList->Count - 1; i >= 0; i--) { delete (TServer *)(pList->Items[i]); pList->Delete(i); } } //--------------------------------------------------------------------------- int __fastcall TServerList::IndexOf(AnsiString asSearch) { for(int i = 0; i < pList->Count; i++) if(asSearch == GetItem(i)->asURL) return i; return -1; } //--------------------------------------------------------------------------- TServer * TServerList::GetItem(int iIndex) { return (TServer *)(pList->Items[iIndex]); } //--------------------------------------------------------------------------- //Load und Save lass ich weg, tut hier nix zur Sache :) Wenn du nicht gerade 100000 Listenelemente hast, kannst du die Klasse nutzen, für richtig große Listen/Vektoren etc. sollte man die VCL-Klassen beseite lassen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz