![]() |
und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Hallo,
ich lerne gerade ein bisschen C++, jedoch verstehe ich die Speicherreservierung von Obijekten/Instanzen nicht so ganz. Am besten zeige ich es an einem Beispiel: // CKlasse ist eine Klasse und hat eine memberfunktion namens "anzahl()" c++ ___
Code:
Wie kann man dies am besten mit Delphi vergleichen?
int aktuelleanzahl = 0;
CKlasse *Klassenvariable = NULL; Klassenvariable = new CKlasse // der Klassenvariable wird eine (referenz?) adresse zugewiesen. aktuelleanzahl = Klassenvariable.anzahl(); // Wieso braucht man hier kein "*"? Ich dachte das man sonst nur auf die speicherdresse(?) zugreifen kann. delete aktuelleanzahl; // Beispiel aus einem anderen Tuturial /* int *zahl = Null; zahl = new int; *zahl = 100; //! hier braucht man den "*" wieder. warum hier schon aber bei "aktuelleanzahl = Klassenvariable.anzahl();" nicht? delete zahl; */ Delphi:
Delphi-Quellcode:
- Bitte beantwortet mir meine zwischenfragen die ich neben den quellcode als kommentar geschrieben habe.
var
anzahl: integer; Klassenvariablenname: TKlasse; begin Klassenvariablenname := TKlasse.Create() anzahl := Klassenvariablenname.anzahl; anzahl.free; end; - Bitte beantwortet mir diese Frage: Welche Zeilen von Delphi wären die gleichen wie in c++? z. B: ("Klassenvariablenname := TKlasse.Create()" in delphi ist das gleiche wie "CKlasse *Klassenvariable = NULL;") - Bitte beantwortet mir diese Frage: Welche Zeilen von c++ wären die gleichen wie in delphi? z. B: "CKlasse *Klassenvariable = NULL;" in delphi ist das gleiche wie ("Klassenvariablenname := TKlasse.Create()") Bitte fragt nach wenn ihr nicht genau verstanden habt was ich eigentlich will (habe es ein bisschen kompliziert ausgedrückt) Danke für eure mühen. Lg Simon |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Es wäre herzallerliebst, wenn du Quelltext auch in Code-Tags/Delphi-Tags setzen würdest.
Und via Google findet man z.B. das hier ![]() |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Danke für deine schnelle antwort.
Leider löst der link mein problem nicht. Bis jetzt konnte ich alles in c++ mit delphi vergleichen. Nun würde ich gerne wissen wie man den jeweiligen Quellcode den ich oben angegeben habe, in der jeweils anderen sprache schreibt. Lg Simon |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Du solltest die Begriffe Referenz und Zeiger nicht durcheinanderbringen.
Zitat:
Normalerweise verwendet man in C++ aber statt "*" und "." "->", dann wird auch besser deutlich, was man da tut.
Code:
pKlassenvariable->anzahl();
|
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Hier mal dein C++ Code in Delphi gefasst
Delphi-Quellcode:
In Delphi erfolgt die Dereferenzierung bei Klassen-Referenz-Variablen automatisch, daher ist dort keine explizite Behandlung notwendig.
program dp_181230;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type CKlasse = class public function anzahl : Integer; end; { CKlasse } function CKlasse.anzahl : Integer; begin Result := 42; end; procedure Foo; var aktuelleanzahl : Integer; // eine einfache Variable Klassenvariable : CKlasse; // eine Klassen-Referenz-Variable zahl : PInteger; // Ein Zeiger auf einen Integer begin // int aktuelleanzahl = 0; aktuelleanzahl := 0; // CKlasse *Klassenvariable = NULL; Klassenvariable := nil; // Klassenvariable = new CKlasse Klassenvariable := CKlasse.Create; // aktuelleanzahl = Klassenvariable.anzahl(); aktuelleanzahl := Klassenvariable.anzahl( ); // delete aktuelleanzahl; // DELPHI: Variablen kann man überschreiben, aber der Speicher sollte nicht freigebeben werden Klassenvariable.Free; // In Delphi notwendig, sonst Speicherleck // int *zahl = Null; zahl := nil; // zahl = new int; new( zahl ); // *zahl = 100; zahl^ := 100; // delete zahl; FreeMem( zahl ); end; begin ReportMemoryLeaksOnShutdown := True; try Foo; except on E : Exception do Writeln( E.ClassName, ': ', E.Message ); end; end. |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
@ Mikkey, ich benute MS visual studio 2013. Möglicherweise habe ich ein falsches beispiel genannt wann man ihn nicht braucht.
Möglicherweise ist hier die verwendung korrekt (wenn ja, warum?):
Code:
@ Sir Rufo, herzlichen danke das wollte ich wissen :)
#include <iostream>
using namespace std; class CSpieler { private: char m_Name[30]; int m_status; public: void init(); void zeigedaten(); }; void CSpieler::init() { cout << "Bitte Namen eingeben:" << endl; cin.ignore(); cin.get(m_Name, 29); m_status = 10; } void CSpieler::zeigedaten() { cout << "Name: " << m_Name << endl; cout << "Status: " << m_status << endl; cout << endl; } int main() { CSpieler *pSpielerliste = NULL; int anzahl; cout << "Wie viele Spieler?" << endl; cin >> anzahl; pSpielerliste = new CSpieler[anzahl]; for (int i = 0; i < anzahl; i++) { cout << "Spieler " << i + 1 << endl; pSpielerliste[i].init(); cout << endl; } for (int j = 0; j < anzahl; j++) { cout << "Spieler: " << j + 1 << endl; pSpielerliste[j].zeigedaten(); cout << endl; } delete[] pSpielerliste; } lg Simon |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Code:
generiert ein Array von Objekten der Typen CSpieler, auf die Elemente eines solchen Arrays greift man (wie in Delphi auch) mit "[..]" zu.
pSpielerliste = new CSpieler[anzahl];
In C werden Arrays und Pointer gleichartig behandelt: "*Ptr" und "Ptr[0]" geben einen Zugriff auf denselben Speicher mit demselben Typ, ebenso wie "(*Ptr).Member", "Ptr->Member" und "Ptr[0].Member". Wenn Du mehr Anforderungen von Code-Transfers von C(++) nach Delphi hast, solltest du Dich mit den C-Grundlagen beschäftigen. |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Danke für deine hilfe.
Das war alles was ich wissen wollte. lg simon |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
@ Sir Rufo, mir sind noch 2 kleine fragen zu diesem Thema eingefallen.
In C++ kann man auch eine Klasse ohne den ganzen Zeiger / referenzen kram erstellen. Wie würde das in Delphi aussehen? Abgesehen davon würde ich gerne wissen ob diese aussage stimmt: "Wenn man in c++ die klasse ohne den Zeiger erstellt dan wird sie im stack gespeichert (und existiert nur in der funktion in der die klasse erstellt wurde)."?
Code:
Klasse CKlasse;
CKlasse.variable = 10; Lg Simon |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Delphi hat dafür kein Pendant, ebensowenig, wie für das Objektarray aus Deinem anderen Beispiel.
In C# wurde das auch abgeschafft. Beide Sprachen bieten wegen der automatischen Dereferenzierung nicht die Syntax, um Objektreferenzen von Objektvariablen zu unterscheiden. |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Zitat:
Am Ehesten kannst due es mir Records in Delphi vergleichen. |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Danke, eure antworten haben mir sehr geholfen.
Ich möchte noch ein kleines beispiel einfügen das mir beim unterscheiden von obijektvariablen und obijektreferenzen geholfen hat: Zitat:
![]() Also wird in delphi von natur aus alles bis auf den Zeiger im heap gespeichert? |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Zitat:
Wenn du das mit dem von C++ vergleichen möchtest, dann liegst du völlig falsch, denn in Delphi entspricht das den Records.
Delphi-Quellcode:
type
THersteller = string[99]; PAuto = ^TAuto; TAuto = record Hersteller : THersteller; constructor Create( Hersteller : THersteller ); end; { TAuto } constructor TAuto.Create( Hersteller : THersteller ); begin Self.Hersteller := Hersteller; end; procedure Test2; var myCar : TAuto; begin myCar := TAuto.Create( 'BMW' ); Writeln( SizeOf( myCar ) ); // -> 100 end; procedure Test3; var myCar : PAuto; begin myCar := New( PAuto ); try myCar^ := TAuto.Create( 'BMW' ); Writeln( SizeOf( myCar ) ); // -> 4 finally Dispose( myCar ); end; end; |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Die C++ Speicherverwaltung lässt sich am besten mit Delphi's
Delphi-Quellcode:
Typ vergleichen:
object
Delphi-Quellcode:
type
CKlasse = object function anzahl: LongInt; end; PCKlasse = ^CKlasse; function CKlasse.anzahl: LongInt; begin anzahl := 42; end; var aktuelleanzahl: LongInt; Klassenvariable: PCKlasse; begin aktuelleanzahl := 0; Klassenvariable := Nil; (* es gibt noch ne spezielle New() Syntax um Konstruktoren mit * Parametern aufzurufen, die müsste ich aber erstmal noch * nachschauen... :/ *) New(Klassenvariable); (* hier wundere ich mich gerade, dass dein C++ Compiler sich nicht * darüber beschwert, dass es Klassenvariable->anzahl() heißen * muss... :/ *) aktuelleanzahl := Klassenvariable^.anzahl; Dispose(Klassenvariable); end. Zitat:
Delphi-Quellcode:
;)
object
Zitat:
Delphi-Quellcode:
und
New
Delphi-Quellcode:
! Das Äquivalent zu
FreeMem
Delphi-Quellcode:
ist
New
Delphi-Quellcode:
und das zu
Dispose
Delphi-Quellcode:
ist
FreeMem
Delphi-Quellcode:
und es gibt einen wichtigen Unterschied zwischen den beiden Paaren: erstes kümmert sich um die Initialisierung/Finalisierung von Managed Typen (Strings (AnsiString, UnicodeString), Interfaces, Dynamische Arrays), aber das zweite Paar macht das nicht. Wenn du also ein
GetMem
Delphi-Quellcode:
mit einem
record
Delphi-Quellcode:
(kein
String
Delphi-Quellcode:
) mit Hilfe von
ShortString
Delphi-Quellcode:
freigibst, dann hast du ein Memoryleak, weil der Referenzzähler des Strings nicht runtergezählt wird.
FreeMem
Gruß, Sven |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Zitat:
|
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Zitat:
Zitat:
Code:
?
{
CKlasse obj(..); CKlasse* ptrObj = new CKlasse(..); CKlasse& refObj = *ptrObj; } |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Danke für eure zahlreichen antworten.
@ Sir Rufus: Ich verstehe nicht was records damit zu tun haben, ich dachte das wäre sowas wie struct(c++) nur für delphi.
Delphi-Quellcode:
Wären die 100 Bytes nicht dank der automatischen derefernzierung trotzdem im heap gespeichert und im stack wird (vom compiler automatisch) ein zeiger darauf hinterlegt? (möglicherweise habe ich es doch falsch verstanden).
procedure Test2;
var myCar : TAuto; begin myCar := TAuto.Create( 'BMW' ); Writeln( SizeOf( myCar ) ); // -> 100 end; Sollte meine oben gennante aussage stimmen, wären dann nicht in delphi selbsterstellte zeiger ziemlich überflüssig? lg Simon |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Du versuchst hier Birnen mit Äpfel zu vergleichen.
C++ arbeitet anders als Delphi und daher muss man eben diese Besonderheiten berücksichtigen und kann da nicht stumpf 1:1 den Code umsetzen. Ein Mazda RX-7 und ein Nissan 370ZX zu vergleichen geht schon (starten, fahren, tanken, ...), aber wenn man dann die Motoren auseinandernimmt ist und vergleichen will, hat man ein Problem, denn es sind 2 grundverschiedene Konzepte (Wankel <-> Otto) und trotzdem können beide fahren. Somit wollte ich nur sagen, dass man das, was du da als C++ Beispiel hattest, in Delphi am ehesten mit Records vergleichen kannst, es ist aber nicht exakt dasselbe. |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Herzlichen danke,
könntest du mir (oder jemand anderes) auch noch diese frage beantworten:
Delphi-Quellcode:
Werden die 100 Bytes dank der automatischen derefernzierung im heap gespeichert und im stack wird (vom compiler automatisch) ein zeiger darauf hinterlegt? (möglicherweise habe ich es falsch verstanden).
procedure Test2;
var myCar : TAuto; begin myCar := TAuto.Create( 'BMW' ); Writeln( SizeOf( myCar ) ); // -> 100 end; lg simon |
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Zitat:
Zitat:
Delphi-Quellcode:
und da gibt es keine automatische Dereferenzierung (Verhält sich ähnlich zu Klassen in C++).
TAuto = record
|
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Zitat:
wenn TAuto keine Klasse wäre, würde
Delphi-Quellcode:
nicht funktionieren :-D
myCar := TAuto.Create( 'BMW' );
|
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Zitat:
|
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
In meinem Delphi hat ein Record keinen Konstruktor und auch keine Klassenfunktionen, die so tun könnten als ob.
|
AW: und C++ Speicherreservierung von Instanzen/Obijekten // (MS visual studio 2013)
Zitat:
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
in Delphi als veraltet gilt stört mich ehrlich gesagt überhaupt nicht. Ich bin FPC Entwickler und dort ist
object
Delphi-Quellcode:
nach wie vor first-class Citizen (und wird zum Beispiel im Compiler selbst noch hier und da verwendet).
object
Referenzvariablen lassen sich in der Tat nicht mit Delphi darstellen (außer als Parameter, wo du
Delphi-Quellcode:
und in FPC
var
Delphi-Quellcode:
verwenden kannst). Andererseits sind Referenzvariablen nicht auf Klassen beschränkt und hier geht es ja um die Speicherverwaltung um Klassen und deren Äquivalenzen in Delphi. Und da ist nun mal
constref
Delphi-Quellcode:
das was am nähesten rankommt...
object
Zitat:
Delphi-Quellcode:
ein Record ist, liegt es auf dem Stack. Bei
TAuto
Delphi-Quellcode:
wird (grob gesagt) auf einer temporären Variable vom Typ
TAuto.Create
Delphi-Quellcode:
auf dem Stack gearbeitet, die an
TAuto
Delphi-Quellcode:
als versteckter Parameter übergeben wird und anschließend an
Create
Delphi-Quellcode:
zugewiesen wird. Ein Record ist nur dann auf dem Heap, wenn du mit
myCar
Delphi-Quellcode:
oder
New
Delphi-Quellcode:
und ner Zeigervariablen (
GetMem
Delphi-Quellcode:
) arbeitest.
type PAuto = ^TAuto;
Zitat:
Gruß, Sven |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:03 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