Eigene Klasse in ein Array packen
-
@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.
-
@john-0 sagte in Eigene Klasse in ein Array packen:
Ach wie nett, deshalb gibt es ja auch die explicit Konstruktoren, damit das nicht geht.
foo("hugo")
... das ist in dem fall kein Funktionsaufruf, das meinte ich damit.
-
@Swordfish sagte in Eigene Klasse in ein Array packen:
foo("hugo")
... das ist in dem fall kein Funktionsaufruf, das meinte ich damit.Konstruktoren sind keine normalen Funktionen, aber wenn foo kein POD ist, wird eine Funktion ausgeführt, außer der Konstruktur ist komplett zur Compilezeit evaluierbar, dann wird es schon beim Übersetzen gemacht.
P.S. POD == plain old data ist eindeutiger als "Basisdatentypen".
-
@john-0 sagte in Eigene Klasse in ein Array packen:
P.S. POD == plain old data ist eindeutiger als "Basisdatentypen".
pod schließt structures mit ein (basistypen die einen constructor haben können). ich würde eher zwischen primitiven und komplexen datentypen unterscheiden.
was ist ein 'basistyp', außer einer definitionslücke?
-
@john-0 ich hab' keine zeit für solchen quatsch. http://eel.is/c++draft/class.ctor#2
-
@Bushmaster sagte in Eigene Klasse in ein Array packen:
pod schließt structures mit ein (basistypen die einen constructor haben können).
http://eel.is/c++draft/depr.meta.types#4
@Bushmaster sagte in Eigene Klasse in ein Array packen:
ich würde eher
http://eel.is/c++draft/basic.types#9
http://eel.is/c++draft/class.prop
-
@SeppJ sagte in Eigene Klasse in ein Array packen:
Placement
new
weint traurig in seiner stillen Ecke, weil nie jemand an es denktNachdem
std::allocator<T>::construct
in C++17 deprecated und C++20 removed ist, wird placementnew
wohl wieder neue Freunde finden.