AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Verwenden von property in C++ Builder
Thema durchsuchen
Ansicht
Themen-Optionen

Verwenden von property in C++ Builder

Ein Thema von messie · begonnen am 19. Jan 2006 · letzter Beitrag vom 20. Jan 2006
Antwort Antwort
messie

Registriert seit: 2. Mär 2005
Ort: Göttingen
1.592 Beiträge
 
Delphi 2009 Professional
 
#1

Verwenden von property in C++ Builder

  Alt 19. Jan 2006, 11:53
Moin,

ich brech' mir gerade einen ab, eine TObjectlist im Builder 6 zu definieren.
Delphi-Quellcode:
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*/
};
Die Stelle mit dem "X" wird vom Compiler angemeckert, Meldung steht darunter.
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
  Mit Zitat antworten Zitat
Benutzerbild von Der Jan
Der Jan

Registriert seit: 22. Dez 2005
289 Beiträge
 
Delphi XE7 Ultimate
 
#2

Re: Verwenden von property in C++ Builder

  Alt 19. Jan 2006, 12:18
Code:
    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
Wenn du in C++ eine Klasse hast kannst du schreiben

Code:
TMyClass t; Klassenvariable wird definiert UND Klasse erzeugt
//oder
TMyClass *p; Zeiger auf Klasse
p = new TMyClass; Erzeugen
Erstere Variante ist bei VCL-Klassen nicht erlaubt.
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

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
Gruß, Jan
  Mit Zitat antworten Zitat
messie

Registriert seit: 2. Mär 2005
Ort: Göttingen
1.592 Beiträge
 
Delphi 2009 Professional
 
#3

Re: Verwenden von property in C++ Builder

  Alt 19. Jan 2006, 14:36
Zitat:
Hoffe, es war halbwegs verständlich
Naja,
ist schon etwas ungewohnt, die Sternchen an die richtige Stelle zu setzen, mache halt sonst nur Delphi..

Zitat:
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
Der Compiler hatte es aber gemerkt, leider ist die Anzeige der Fehlerposition bei weitem nicht so gut wie im Delphi - erinnert ein wenig an TP-Zeiten.

Hänge leider gleich an der nächsten Stelle: Das Erzeugen und Füllen der Objectlist mache in einer anderen Unit mit
Delphi-Quellcode:
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 */
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.

Grüße, Messie
  Mit Zitat antworten Zitat
Benutzerbild von Der Jan
Der Jan

Registriert seit: 22. Dez 2005
289 Beiträge
 
Delphi XE7 Ultimate
 
#4

Re: Verwenden von property in C++ Builder

  Alt 19. Jan 2006, 15:11
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 von messie:
Der Compiler hatte es aber gemerkt, leider ist die Anzeige der Fehlerposition bei weitem nicht so gut wie im Delphi - erinnert ein wenig an TP-Zeiten.
Im Gegenteil. Die Anzeige ist genauer. C/C++ ist viel freier als Pascal und der Compiler meckert erst dort, wo dann wirklich ein Fehler auftritt bzw. wo sich dein Fehler dann als solcher bemerkbar macht. Läßt sich schlecht erklären ohne einen Exkurs in die Tiefen von C++ zu unternehmen.

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]
Gruß, Jan
  Mit Zitat antworten Zitat
messie

Registriert seit: 2. Mär 2005
Ort: Göttingen
1.592 Beiträge
 
Delphi 2009 Professional
 
#5

Re: Verwenden von property in C++ Builder

  Alt 19. Jan 2006, 15:28
Zitat:
Auf Arbeit muß ich Delphi...
Gibt bestimmt Schlimmeres!
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
Ich warte also lieber bis heute abend...

Grüße, Messie
  Mit Zitat antworten Zitat
Benutzerbild von Der Jan
Der Jan

Registriert seit: 22. Dez 2005
289 Beiträge
 
Delphi XE7 Ultimate
 
#6

Re: Verwenden von property in C++ Builder

  Alt 20. Jan 2006, 10:44
Uh, sorry Jetzt fällt mir glatt ein was ich vergessen hab.... Heut abend denk ich dran...
Gruß, Jan
  Mit Zitat antworten Zitat
messie

Registriert seit: 2. Mär 2005
Ort: Göttingen
1.592 Beiträge
 
Delphi 2009 Professional
 
#7

Re: Verwenden von property in C++ Builder

  Alt 20. Jan 2006, 12:29
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
  Mit Zitat antworten Zitat
Benutzerbild von Der Jan
Der Jan

Registriert seit: 22. Dez 2005
289 Beiträge
 
Delphi XE7 Ultimate
 
#8

Re: Verwenden von property in C++ Builder

  Alt 20. Jan 2006, 23:37
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:
//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
Ich hoffe es nützt was. Wenn nicht, frag ruhig. Wenns nötig auch per PM

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.
Gruß, Jan
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz