Forum: PC-Programmierung unverständliche C++ Codeabschnitt


von Sami (Gast)


Lesenswert?

Hallo zusammen:
Ich habe einen Projekt von einen Kollegen übernommen.
Dieses Projekt beinhaltet leider keine Dokumentation.

Ich bin auf einen Codeabschnitt gestossen, die ich nicht verstehe:

#define pmaGetAClass()        ((AClass *)m_pvAClass)


Was passiert eigentlich?
Ist dieses Macro nötig?
Kann ich das anders schreiben?
Was bekomme ich, wenn ich pmaGetAClass() aufrufe?

Der zweite Abschnitt sieht so aus:

#define pmaGetBClassBySlot(a)  (&((CBClass *)m_pvBClassPool)[static_cast 
<int>(a)])

Hier ist auch das gleiche.
Was passiert?
Ist das nötig?
Kann ich das anders schreiben?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sami schrieb:
> Ist dieses Macro nötig?

Wenn es benutzt wird: ja, natürlich.

> Was passiert eigentlich?

Na, das steht doch da. Die Membervariable m_pvAClass wird in einen 
Pointer auf AClass gecastet.

Welchen Typ hat m_pvAClass?

von Sami (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Welchen Typ hat m_pvAClass?
void *m_pvAClass;
void *m_pvBClassPool;

von Rene H. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Welchen Typ hat m_pvAClass?

Das wird vermutlich ein void * sein. Das ist aber nur eine Vermutung.

Grüsse,
René

von Jay (Gast)


Lesenswert?

Macros sind nie absolut "nötig", man kann den Code auch direkt x-fach 
kopieren und hinschreiben - was aber ziemlich nervig ist. Bei C++ gibt 
es in vielen Fällen auch bessere Alternativen zu Macros, z.B. Templates. 
Soviel zur Sinnfrage - die Macros "nötig" sein oder auch nicht.

Ansonsten sind das sehr einfache C++-Konstrukte. Bist du sicher, dass du 
C++ kannst und Casting verstehst?

Zu eigentlichen Code kann man nicht viel sagen, also da wo die Macros 
verwendet werden, da du den Code nicht gezeigt hast. Man kann vermuten, 
dass man insgesamt den Code vernünftiger aufbauen kann, z.B. in dem von 
vorne herein auf Typkompatibilität geachtet wird. Vielleicht bietet sich 
auch ein Operator-Overloading von [] an, und zur Not Templates.

von Sami (Gast)


Lesenswert?

Jay schrieb:
> Ansonsten sind das sehr einfache C++-Konstrukte. Bist du sicher, dass du
> C++ kannst und Casting verstehst?

Ja das verstehe ich.

Dieses Casten ist aber c-spezifisch sollte man vielleicht nicht c++ 
spezifisch casten?

--> Das ist eigentlich der saubere Weg denke ich

von Rene H. (Gast)


Lesenswert?

Sami schrieb:
> Dieses Casten ist aber c-spezifisch sollte man vielleicht nicht c++
> spezifisch casten?
>
> --> Das ist eigentlich der saubere Weg denke ich

Natürlich sollte man. Man sollte aber auch void* vermeiden ;-). Das 
lässt sich garantiert besser implementieren.

Grüsse,
René

von Rolf M. (rmagnus)


Lesenswert?

Sami schrieb:
> Dieses Casten ist aber c-spezifisch sollte man vielleicht nicht c++
> spezifisch casten?

Man sollte es so umschreiben, dass man keinen Cast braucht.
In C++ braucht man eigentlich nur selten Casts - oder Makros.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sami schrieb:
> Dieses Casten ist aber c-spezifisch sollte man vielleicht nicht c++
> spezifisch casten?

Allerdings; dieser "C++"-Code ist aus C++-Sicht ziemlicher Pfusch und 
bei sauber geschriebenem C++ so auch absolut unnötig.

von Tom (Gast)


Lesenswert?

Rene H. schrieb:
> Das
> lässt sich garantiert besser implementieren.

Könnte man. Aber im geerbten Projekt erstmal alles "aufzuräumen", ist 
vielleicht etwas für Menschen, die etwas erfahrener sind.
Wenn es läuft: so lassen. Wenn man es nicht ganz versteht: so lassen. 
Wenn man es irgendwann sowieso anfassen muss oder wenn Zeit für 
Refactoring ist: besser machen, falls man verstanden hat, wie es besser 
geht.

von Eric B. (beric)


Lesenswert?

Sami schrieb:
> #define pmaGetBClassBySlot(a)  (&((CBClass *)m_pvBClassPool)[static_cast
> <int>(a)])

Interessant ist allerdings dass hier einmal "C-Style" gecastet wird und 
einmal "C++-Style". Da hat wohl ein C-Programmierer C++ Code schreiben 
wollen oder müssen.

von Sami (Gast)


Lesenswert?

Rene H. schrieb:
> Man sollte aber auch void* vermeiden ;-)

zu verstehen: Warum sollte es einen void* vermieden werden?
Danke

von Daniel A. (daniel-a)


Lesenswert?

Man sollte void pointer vermeiden, weil man nicht weiss auf welchen 
Datentyp er zeigt. Es gibt sinvolle Anwendungsfälle dafür, wie z.B. bei 
functionen wie memset, memcpy wo der Datentyp keine rolle spielt. Für 
alles andere muss man den void pointer in den eigentlichen Datentyp 
casten, und wenn man den falchen erwicht ist man aufgeschmissen. In C++ 
kann man die meisten void pointer vermeiden, indem man den möglichen 
Typen die selbe Basisclasse für ein einheitliches Interface hat oder 
Templates einsetzt.

von Robert L. (lrlr)


Lesenswert?

>weil man nicht weiss auf welchen
>Datentyp er zeigt.

das verhindert man mit:


>indem man den möglichen
>Typen die selbe Basisclasse

verwendet

aber auch nicht automatisch


d.h. man sollte einen CAST immer nur mit dynamischer TypPrüfung machen..

: Bearbeitet durch User
von Daniel A. (daniel-a)


Lesenswert?

@Robert L. (lrlr)
Das mag ja sein, dennoch entfällt durch eine Basisklasse mit sauberem 
Interface und einigen virtuellen Methoden meistens die Notwendigkeit den 
eigentlichen typ zu kennen. Ansonsten traue ich den Dynamic cast 
geschichten nicht wirklich und versuche solche Situationen immer zu 
vermeiden.

von lrlr (Gast)


Lesenswert?

stimmt auch wieder..

von Sven B. (scummos)


Lesenswert?

> Ansonsten traue ich den Dynamic cast
> geschichten nicht wirklich und versuche solche Situationen immer zu
> vermeiden.

??

Robert L. schrieb:
> d.h. man sollte einen CAST immer nur mit dynamischer TypPrüfung machen..

???

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.