Eigene Klasse in ein Array packen
-
@torsten_156 sagte in Eigene Klasse in ein Array packen:
TSpieler *MySpieler[5] = new TSpieler;
Du versuchst hier ein Array eines Pointers auf TSpieler zu erzeugen und kein Array von TSpieler.
Außerdem willst du ja scheinbar 5 spieler erzeugen. Dein "new TSpieler" würde aber nur einen erzeugen. Da solltest du stutzig werdenSo würde ich das machen:
std::vector<TSpieler> PlayerList( 5 );
Das erzeugt fünf Instanzen von "TSpieler".
Und mitPlayerList[ 0 ] PlayerList[ 1 ] usw...
Kannst du draufzugreifen.
-
Dumme Frage: Ist deine TSpieler-Klasse eine VCL-Klasse? Also erbt sie von TObject? Denn dann gelten spezielle Regeln (wie bei Delphi) und du musst Pointer verwenden (und mein Wissen endet hier).
In "normalem" C++, also wenn du nicht von TObject erben musst, wäre natürlich der
std::vector<TSpieler>
die richtige Lösung.
-
@wob sagte in Eigene Klasse in ein Array packen:
Denn dann gelten spezielle Regeln (wie bei Delphi) und du musst Pointer verwenden (und mein Wissen endet hier).
Das gilt nur für
TComponent
s,TObject
s können sehr wohl auf dem Stack leben (und mein Wissen endet hier).
-
@Swordfish Immer diese Misinformation aus Büchern, die man sich mühsam ergooglet! Seite 881 oben hier: https://books.google.de/books?id=UNIiBgAAQBAJ&pg=PA883&lpg=PA883&dq=vcl+class+c%2B%2B&source=bl&ots=OIBs9cvsQa&sig=ACfU3U3Z8rglNA1ut1fGoP8RmXNDiUbqow&hl=de&sa=X&ved=2ahUKEwjG04mDqOrnAhWj0KYKHZp9AD8Q6AEwCnoECAkQAQ#v=onepage&q=vcl class c%2B%2B&f=false
(mein Interesse, weil Delphi 2 (damals mühsam vom Taschengeld gekauft für ca. 200 DM) nach Turbo Pascal meine 2. Programmiersprache war)
-
Dieser Beitrag wurde gelöscht!
-
Nein, alle VCL-Objekte (also von
TObject
abgeleitete Klassen) müssen mitnew
alloziert werden.
Dies gilt z.B. auch für die Utility-Klasse TStringList, welche nicht vonTComponent
abgeleitet ist.
Eine Ausnahme gibt es nur bei den String-Klassen AnsiString/WideString/UnicodeString, da diese in Delphi eingebaute Datentypen sind (und nicht vonTObject
abgeleitet sind) und in C++ als Klassen re-implementiert wurden (auf der Grundlage von AnsiStringBase).PS: Die Fehlermeldung lautet auch E2459 Delphi style classes must be constructed using operator new (bzw. früher "E2459 VCL style classes must be constructed using operator new").
-
@Th69 Nicht daß ich Dir nicht glaube ... nur warum ist das dann in VCL Overview für
TComponent
explizit erwähnt und fürTObject
nicht?
-
@Th69 sagte in Eigene Klasse in ein Array packen:
Nein, alle VCL-Objekte (also von TObject abgeleitete Klassen) müssen mit new alloziert werden.
Dies gilt z.B. auch für die Utility-Klasse TStringList, welche nicht von TComponent abgeleitet ist.warum diese einschränkung? scheinbar ist beim c++builder nicht nur die ide schlecht. man liest ja ständig beschwerden darüber.
-
@Swordfish: Du meinst
- Components can only be allocated on the heap, not on the stack.
?
Das ist nur als Abgrenzung zu dem Hauptsatz darüberBut there are differences between components in Delphi and the standard class hierarchies that many programmers work with. Some differences are:
zu sehen.
In Delphi wird der Heap automatisch benutzt, sobald man den KonstruktorCreate
aufruft (s.a. Understanding Memory Allocation in Delphi unter "What Is Heap?"), welches für alle vonTComponent
- als auch von TObject - abgeleiteten Klassen gilt.
Und somit muß in C++ (beim C++Builder/RADStudio) explizitnew
benutzt werden (damit die Speicherfreigabe überdelete
bzw. das Delphi-ÄquivalentFree
automatisch erfolgen kann) - ähnlich wie bei Qt und dessenQWidget
-Klassen, sobald diese als Children zu einer Containerklasse wieQWindow
hinzugefügt werden (und dann bei Freigabe automatisch alle Children perdelete
freigegeben werden).
-
@Th69 Ah mist, ich habe von Q... Dingen auf T...Dinge geschlossen. Danke, auch für die Links.
-
Dieser Beitrag wurde gelöscht!
-
@m1chak sagte in Eigene Klasse in ein Array packen:
Konstruktoraufruf
Konstruktoren kann man nicht explizit aufrufen.
@m1chak sagte in Eigene Klasse in ein Array packen:
Damit ist die Initialisierung des Arrays:
Deklaration.
-
@torsten_156
Hallo Thorsten,
hier die Lösung ohne "Workaround":Dein Array soll fünf Adressen auf TSpieler-Objekte beinhalten.
Also ist der Datentyp des Arrays:TSpieler* ... sprich "TSpieler Adresse".
Damit ist die Initialisierung des Arrays:
TSpieler* mySpieler[5];
Das hast Du im Prinzip richtig erkannt. Objekte üblicher Weise mit kleinem Anfangsbuchstaben.
So. In den fünf Feldern stehen jetzt aber noch keine Adressen drin, weil Du ja noch keine fünf Spieler hast. Da lag dein Denkfehler:
mySpieler[0] = new TSpieler( ); // Die Parameterklammern darf man weg lassen, aber eigentlich ist das ein Konstruktoraufruf von TSpieler, also mit ( ).
und so weiter:
mySpieler[1] = new TSpieler( );
mySpieler[2] = new TSpieler( );
mySpieler[3] = new TSpieler( );
mySpieler[4] = new TSpieler( );Später dann, wie Du vermutlich weisst:
mySpieler[3] -> machWas();
Viel Spaß damit.
-
"Konstruktoren kann man nicht explizit aufrufen" ...
int x(42);
print(x);"Damit ist die Initialisierung des Arrays"...
Das stimmt
-
@m1chak sagte in Eigene Klasse in ein Array packen:
"Konstruktoren kann man nicht explizit aufrufen" ...
int x(42);
print(x);Was willst Du mir sagen, daß ein
int
eger einen Konstruktor hat?
-
@Swordfish Alle Objekte haben einen Konstruktor. Erzeugung im Speicher immer zweistufig:
-
Speicher allokieren.
-
Speicherinhalt beim Konstruktordurchlauf manipulieren.
-
Immer, 2) beim Aufruf.
Anderes Beispiel:
class A
{
};A* a = new A(); Defaultkonstruktor (gibts immer)
aber:
class A
{
A()
{ echo("Hallo");}
};dann führt A* a = new A(); zu "Hallo"
und mit
class A
{
A()
{ echo("Hallo");}A(int x)
{ echo(x);}
};... kann ich mir aussuchen, welchen Konstruktor ich will:
A* a1 = new A();
A* a2 = new A(42);
-
-
@Swordfish sagte in Eigene Klasse in ein Array packen:
@m1chak sagte in Eigene Klasse in ein Array packen:
Konstruktoraufruf
Konstruktoren kann man nicht explizit aufrufen.
Placement
new
weint traurig in seiner stillen Ecke, weil nie jemand an es denkt
-
@SeppJ sagte in Eigene Klasse in ein Array packen:
Placement
new
weint traurigDein Ernst?
@m1chak Na schön, dann ruf' einen Konstruktor explizit auf. Basisdatentypen haben aber trotzdem keinen, das kannst Du rumdrehen wie Du willst.
-
@m1chak sagte in Eigene Klasse in ein Array packen:
int x(42);
diese schreibweise ist irreführend. was passiert bei 'int x;' ?
aufruf eines default-konstruktors der nichts macht?
und warum wird plötzlich ein verstecktes 'int x(0);' daraus, wenn x keine lokale variable ist?
ich nehme an, diese schreibweise existiert, damit man primitive typen in templates und makros so verwenden kann, als wären es klassen.
-
@Swordfish sagte in Eigene Klasse in ein Array packen:
@m1chak sagte in Eigene Klasse in ein Array packen:
Konstruktoraufruf
Konstruktoren kann man nicht explizit aufrufen.
Ach wie nett, deshalb gibt es ja auch die
explicit
Konstruktoren, damit das nicht geht.