Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

11

15.01.2007, 12:32

Zitat von »"Draculark"«

ja schon^^

nur das hier:

C-/C++-Quelltext

1
inline void DeletePtr( T*& ptr ) 


verwirrt bischen. eine templatepointerreferenz? klingt irgendwie abartig...


Wie dir sicher aufgefallen ist, handelt es sich bei diesem Anzatz auch gar nicht um die Methode einer Klasse. Um dann nicht für jeden Typ eine eigene Funktion schreiben zu müssen, gibt es eben eine Template-Funktion. Wo ist das Problem?

Deine Implementation benutzt auch ein überflüssiges Argument, weil die den "this" Zeiger selbst noch als Parameter übergibst. Wenn du die Methode statisch deklarierst, stellt sich hinterher auch die Frage eines "delete innerhalb einer nicht statischen Methode" nicht. (Das klappt, wenn gleich danach ein return / Methodenende kommt, ist aber schlechter Programmierstil)

Ausserdem ist es völlig in Ordnung eine Referenz auf einen Zeiger zu übergeben, wenn man den Zeiger innerhalb der Methode auch ändern will. Stilistisch wäre IMHO allerdings eine Übergabe als "Zeiger auf Zeiger" netter, weil man dann leichter sehen kann, dass der übergebene Wert geändert wird.

Andererseits ist so ein Template auch gefährlich, weil der Compiler dann solche Fehler nicht mehr erkennt:

C-/C++-Quelltext

1
2
3
4
5
MyClass* my_class = new MyClass;
MyClass* my_class_array = new MyClass[10];

DeletePtr (&my_class); // falsch, weil DeletePtr<MyClass**>

DeletePtr (my_class_array); // falsch, weil nicht delete[] benutzt wird


Wie man es auch macht, selbst aufpassen muss man halt auch immer.

Noch eine Bemerkung am Rande: Eigentlich ist es nur Augenwischerei, einen Zeiger nach einem delete auch noch mit Null zu belegen, weil das nämlich immernoch nicht sicherstellt, dass wirklich alle Zeiger, die mal auf das Objekt gezeigt haben, Null sind. Sowas hilft nur, wenn wirklich sicher ist, dass es nur einen einzigen Zeiger auf das fragliche Objekt gibt. Wenn ich solche Objekte freigebe, fällt der Zeiger als nächstes immer aus der Liste meiner verwalteten Objekte raus, und damit gibt es dann auch gar keinen Zeiger mehr. Warum also nullen?

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

12

15.01.2007, 13:02

Zitat von »"rklaffehn"«


Ausserdem ist es völlig in Ordnung eine Referenz auf einen Zeiger zu übergeben, wenn man den Zeiger innerhalb der Methode auch ändern will. Stilistisch wäre IMHO allerdings eine Übergabe als "Zeiger auf Zeiger" netter, weil man dann leichter sehen kann, dass der übergebene Wert geändert wird.


In dem Fall mag das egal sein. An anderen Stellen bekommt man aber wieder das Problem von 0-Zeiger-Zeigern. D.h. wieder zusätzliche Tests.
Aßerdem ist die Syntax, mit den ganzen Dereferenzierungsoperatoren, tatsächlich nicht jedermanns Sache.
Mit Referenz auf einen Zeiger wird ja auch klar das der Zeiger voraussichtlich geändert wird, solange man sich die Mühe macht und die Funktionsdeklaration ansieht.

Zitat von »"rklaffehn"«


Andererseits ist so ein Template auch gefährlich, weil der Compiler dann solche Fehler nicht mehr erkennt:

C-/C++-Quelltext

1
2
3
4
5
MyClass* my_class = new MyClass;
MyClass* my_class_array = new MyClass[10];

DeletePtr (&my_class); // falsch, weil DeletePtr<MyClass**>

DeletePtr (my_class_array); // falsch, weil nicht delete[] benutzt wird


Wie man es auch macht, selbst aufpassen muss man halt auch immer.


Erstes Beispiel sollte vom Compiler als falsch erkannt werden. Zweites Beispiel ist tatsächlich ein kleines Problem. Dieses tritt aber immer auf bei der Verwendung von delete und delete[]. Hier hat der Programmierer sowiso acht zu geben. :)
@D13_Dreinig

Steven77

Alter Hase

Beiträge: 515

Wohnort: Münster - Gievenbeach

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

13

15.01.2007, 13:21

Zitat von »"David_pb"«

[...] Dieses tritt aber immer auf bei der Verwendung von delete und delete[]. Hier hat der Programmierer sowiso acht zu geben. :)

Genau, daher bieten sich zwei Methoden an:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
template <typename T>
void DeletePtr(T*& ptr)
{
    delete ptr;
    ptr = NULL;
}

template <typename T>
void DeleteAry(T*& ary)
{
    delete[] ary;
    ary = NULL;
}

Das kann man von einem Programmierer wohl erwarten, dass er darauf achtet, welche Methode zu benutzen ist, sofern er den Unterschied zwischen delete und delete[] verstanden hat.
Kommen Sie nie mit einem Schwert zu einer Schießerei.

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

14

15.01.2007, 17:47

Zitat von »"David_pb"«

Zitat von »"rklaffehn"«


C-/C++-Quelltext

1
DeletePtr (&my_class); // falsch, weil DeletePtr<MyClass**>


Erstes Beispiel sollte vom Compiler als falsch erkannt werden.


Hmm, du hast natürlich recht, das klappt so nicht. :) Ausserdem wäre das Template DeletePtr<MyClass*> gewesen.

Da sieht man mal wieder, dass man auch negativ-Fälle einfach mal ausprobieren sollte ;) Ich gelobe Besserung. Das war nur, weil ich weder die eine noch die andere Variante benutzen würde.

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Werbeanzeige