Forum: PC-Programmierung C++ Review bzw. Feadback


von dominik_ (Gast)


Lesenswert?

1
class A: public QObject
2
{
3
  Q_OBJECT
4
  
5
  public:
6
  EFILIBRARY_EXPORT A(bool boPower);
7
  EFILIBRARY_EXPORT ~A();
8
  .....
9
  signals:
10
  .....
11
  
12
  
13
  private:
14
  
15
  void *m_pvBclass;     // Bclass ist einen class 
16
  void *m_pvDclassPool; // DclassPool ist einen class
17
  void *m_pvEclassHold; //EclassHold ist einen class
18
  
19
  #define pmaGetBclass()      ((Bclass *) m_pvBclass) 
20
  #define pmaGetDclassPool() ((DclassPool *) m_pvDclassPool)  
21
  #define pmaGetEclassHold(a) (&((EclassHold*) m_pvEclassHold) [static_cast <int>(a)])
22
  
23
  ....
24
};

Mir geht darum vorallem um folgende:
1
...
2
private:
3
  
4
void *m_pvBclass;     // Bclass ist einen class 
5
void *m_pvDclassPool; // DclassPool ist einen class
6
void *m_pvEclassHold; //EclassHold ist einen class
7
  
8
#define pmaGetBclass()      ((Bclass *) m_pvBclass) 
9
#define pmaGetDclassPool() ((DclassPool *) m_pvDclassPool) 
10
#define pmaGetEclassHold(a) (&((EclassHold*) m_pvEclassHold) [static_cast <int>(a)])

Es ist echt scheisse implementiert.

von Bob (Gast)


Lesenswert?

dominik_ schrieb:
> Es ist echt scheisse implementiert.

Da kann ich Dir nur voll zustimmen!

von dominik_ (Gast)


Lesenswert?

und wie kann ich das besser implementieren?

von Sebastian V. (sebi_s)


Lesenswert?

Statt void Pointer richtige Pointer auf die entsprechende Klasse. Dann 
die nicht mehr nötigen Makros loswerden.

von Oliver S. (oliverso)


Lesenswert?

Wenns nicht irgendwo anders noch ein ganz abstrusen Trick verwendet 
wird, der die void Pointer braucht.

Wenn nicht, die member Variablen mit ihrem richtigen Typ anlegen, und 
die Setter/Getter als normale Zugriffsfunktionen im Header 
implementieren.

Oliver

: Bearbeitet durch User
von dominik_ (Gast)


Lesenswert?

das hier:
1
  private:
2
  void *m_pvBclass;     // Bclass ist einen class 
3
  void *m_pvDclassPool; // DclassPool ist einen class
4
  void *m_pvEclassHold; //EclassHold ist einen class
kann es so umgeschrieben werden:
1
std::unique_ptr<Bclass> m_Bclass;
2
std::unique_ptr<DclassPool> m_DclassPool;
3
std::unique_ptr<EclassHold> m_EclassHold;

und die FunktionsMacros? Sorry
1
  #define pmaGetBclass()      ((Bclass *) m_pvBclass) 
2
  #define pmaGetDclassPool() ((DclassPool *) m_pvDclassPool)  
3
  #define pmaGetEclassHold(a) (&((EclassHold*) m_pvEclassHold) [static_cast <int>(a)])

von Daniel A. (daniel-a)


Lesenswert?

Ich empfehle dir dich zuerst über Smartpointer zu informieren:
http://de.cppreference.com/w/cpp/memory/unique_ptr
http://de.cppreference.com/w/cpp/memory

Smartpointer sind dazu da die Lebenszeit der Objekte auf die sie Zeigen 
zu verwalten, und diese automatisch freizugeben wen sie nichtmehr 
verwendet werden.

Den Unique Pointer kannst du nur verwenden, wenn du willst, das nur 
dieser eine Pointer darauf existiert, und das Objekt automatisch 
freigegeben wird sobald der Unique Pointer nichtmehr existiert.

Da wir nicht wissen, wozu der Pointer weiterverwendet wird, können wir 
dir auch nicht sagen, ob du ihn hier verwenden kannst. Es ist aber 
relativ wahrscheinlich, dass du normale Pointer verwenden kannst:
1
Bclass* m_Bclass;
2
DclassPool* m_DclassPool;
3
EclassHold* m_EclassHold;

Zu den Funktionsmakros:
1
Bclass* pmaGetBclass(){
2
  return m_pvBclass;
3
}
4
 
5
DclassPool* pmaGetDclassPool(){
6
  return m_pvDclassPool;
7
}
8
9
EclassHold* pmaGetEclassHold( int a ){
10
  return m_pvEclassHold + a; // oder &pvEclassHold[a]
11
}

PS: Das war wohl nichts mit Stack-Overflow, XD
http://stackoverflow.com/questions/36093300/feedback-on-my-spaghetti-code
http://codereview.stackexchange.com/questions/123526/how-can-i-write-the-macro-method-better-please-feadback

: Bearbeitet durch User
von dominik_ (Gast)


Lesenswert?

10000 danke

von dominik_ (Gast)


Lesenswert?

Hallo,
noch eine kurze Frage, bei diese:
1
EclassHold* pmaGetEclassHold( int a ){
2
  return m_pvEclassHold + a; // oder &pvEclassHold[a]
3
}
bekomme ich diese Fehlermeldung:
1
 error C2036: 'EclassHold*' : unknown size

von Daniel A. (daniel-a)


Lesenswert?

dominik_ schrieb:
> Hallo, noch eine kurze Frage, bei diese:
> bekomme ich diese Fehlermeldung:
> error C2036: 'EclassHold*' : unknown size

Grundlagen! Der Compiler weiss wohl schon, dass EclassHold eine klasse 
ist, aber nicht, was diese beinhaltet oder wie gross sie ist. Ersetze 
die Implementierungen mit Prototypen und packe die Implementierung in 
ein cpp file. Beim Cpp file bindest du alle klasse ein, die du benötigst 
(A und EclassHold)
1
// prototypen
2
Bclass* pmaGetBclass();
3
DclassPool* pmaGetDclassPool();
4
EclassHold* pmaGetEclassHold( int a );
1
// Cpp file
2
#include <path/to/a.hpp>
3
#include <path/to/EclassHold.hpp>
4
5
Bclass* A::pmaGetBclass(){
6
  return m_pvBclass;
7
}
8
 
9
DclassPool* A::pmaGetDclassPool(){
10
  return m_pvDclassPool;
11
}
12
13
EclassHold* A::pmaGetEclassHold( int a ){
14
  return m_pvEclassHold + a; // oder &pvEclassHold[a]
15
}

: Bearbeitet durch User
von dominik_ (Gast)


Lesenswert?

Hallo Daniel,

danke es funktioniert aber es ist mit sehr grosse vorsicht zu geniessen.


Die Ressourcen:
1
Bclass* m_Bclass;
2
DclassPool* m_DclassPool;
3
DclassPool* m_EclassHold;
teilen mehrere Zeigern. Also es kommt dann shared_ptr zu verwendung.

Da ich Visual Studio 2008 benutze, kann ich nicht die Neuerungen in C11 
leider nicht davon gebarucht machen.
Ich habe die neue Boost1_60 Library runtergeladen und in Visual Studio 
eingebunden.

Wie soll denn die Zeiger aussehen?

-> Hier ist meinen Versuch:
1
  
2
  typedef boost::shared_ptr<Bclass>m_Bclass;
3
  typedef boost::shared_ptr<DclassPool>m_DclassPool;
4
  typedef boost::shared_ptr<DclassPool>m_EclassHold;
Ist das richtig so?

von Oliver S. (oliverso)


Lesenswert?

Wie die Zeiger aussehen sollen, kommt darauf an, wie sie genutzt werden.

Oliver

von Daniel A. (daniel-a)


Lesenswert?

dominik_ schrieb:
> Die Ressourcen:
...
> teilen mehrere Zeigern. Also es kommt dann shared_ptr zu verwendung.
>
> Da ich Visual Studio 2008 benutze, kann ich nicht die Neuerungen in C11
> leider nicht davon gebarucht machen.

C11 ist der falsche Standard. Du meinst C++11.


> Wie soll denn die Zeiger aussehen?
...
> Ist das richtig so?

Das typedef gehört da nicht hin, es sei denn du möchtest Datentypen 
statt Variablen definieren.

von dominik_ (Gast)


Lesenswert?

@

das stimmt typedef gehört nicht hin:
1
 boost::shared_ptr<Bclass>m_Bclass;
2
 boost::shared_ptr<DclassPool>m_DclassPool;
3
 boost::shared_ptr<DclassPool>m_EclassHold;

von dominik_ (Gast)


Lesenswert?

und wie sollen bitte die Funktionen implementiert werden?

von Daniel A. (daniel-a)


Lesenswert?

Ich kenne mich mit boost nicht aus, vermutlich:
1
// Header file
2
boost::shared_ptr<Bclass> m_Bclass;
3
boost::shared_ptr<DclassPool> m_DclassPool;
4
boost::shared_array<DclassPool> m_EclassHold;
5
6
// cpp file
7
8
boost::shared_ptr<Bclass> A::pmaGetBclass(){
9
  return m_pvBclass;
10
}
11
 
12
boost::shared_ptr<DclassPool> A::pmaGetDclassPool(){
13
  return m_pvDclassPool;
14
}
15
16
Bclass& A::pmaGetEclassHold( int a ){
17
  return m_pvEclassHold[a];
18
}

: Bearbeitet durch User
von PittyJ (Gast)


Lesenswert?

Braucht man boost da überhaupt? Geht das nicht ohne?
Letztens habe ich einen Vortrag gehört, deren Tenor war, dass boost 
durch Features von C++-14 komplett ersetzt werden könnte.
Was ist der Vorteil, wenn man da immer noch diese Extra-Bibliothek 
verwendet?

von Andre R. (physicist)


Lesenswert?

PittyJ schrieb:
> Braucht man boost da überhaupt? Geht das nicht ohne?
> Letztens habe ich einen Vortrag gehört, deren Tenor war, dass boost
> durch Features von C++-14 komplett ersetzt werden könnte.
> Was ist der Vorteil, wenn man da immer noch diese Extra-Bibliothek
> verwendet?

boost ist eine Art (inoffizielle) Testbench für Dinge die zukünftig in 
den Standard fließen und wenn er einen aktuelleren Compiler benutzen 
würde, dann hättest Du recht, aber:

> Da ich Visual Studio 2008 benutze, kann ich nicht die Neuerungen in C11
> leider nicht davon gebarucht machen.

Das Ding ist leider Steinzeit.

Und natürlich gibt es laufend neues in boost.

Wobei ich auch die Frage stellen würde, ob ein Umstieg auf eine 
aktuellere Version nicht in Frage kommt, auch wenn dies ggf. mit 
Anpassungen verbunden sein kann.

: Bearbeitet durch User
von dominik_ (Gast)


Lesenswert?

Daniel A. schrieb:
> Bclass& A::pmaGetEclassHold( int a ){
>   return m_pvEclassHold[a];
> }

ich bekomme folgende Fehlermeldung:
1
 error C2040: 'A::pmaGetEclassHold' : 'A&(int)' differs in levels of indirection from 'boost::shared_array<T> (int)'
2
2>        with
3
2>        [
4
2>            T=A
5
2>        ]

von Daniel A. (daniel-a)


Lesenswert?

Ups, hatte beim Kopieren der Datentypen nicht aufgepasst:
1
// Header file
2
boost::shared_ptr<Bclass> m_Bclass;
3
boost::shared_ptr<DclassPool> m_DclassPool;
4
boost::shared_array<EclassHold> m_EclassHold;
5
6
// cpp file
7
8
boost::shared_ptr<Bclass> A::pmaGetBclass(){
9
  return m_pvBclass;
10
}
11
 
12
boost::shared_ptr<DclassPool> A::pmaGetDclassPool(){
13
  return m_pvDclassPool;
14
}
15
16
EclassHold& A::pmaGetEclassHold( int a ){
17
  return m_pvEclassHold[a];
18
}

von dominik_ (Gast)


Lesenswert?

1
// Header file
2
boost::shared_ptr<Bclass> m_Bclass;
3
boost::shared_ptr<DclassPool> m_DclassPool;
4
boost::shared_array<EclassHold> m_EclassHold;
5
6
boost::shared_ptr<Bclass>pmaGetBclass();
7
boost::shared_ptr<DclassPool>pmaGetDclassPool();
8
EclassHold& A::pmaGetEclassHold( int a );
9
10
boost::shared_ptr<Bclass> A::pmaGetBclass(){
11
  return m_pvBclass;
12
}
13
 
14
boost::shared_ptr<DclassPool> A::pmaGetDclassPool(){
15
  return m_pvDclassPool;
16
}
17
18
EclassHold& A::pmaGetEclassHold( int a ){
19
  return m_pvEclassHold[a];
20
}

So passt danke

von dominik_ (Gast)


Lesenswert?

Noch eine Frage bitte:

ich habe sehr viele funktionen, die so in der Form sind:
1
static void fkt_1(Bclass* bClass_p, DclassPool* dClass_p);
2
static void fkt_2(Bclass* bClass_p, DclassPool* dClass_p, EclassHold*eClassHold);
3
....


Das heisst alle Funktionen müssen umgeschrieben werden so ungefähr:
1
static void fkt_1(boost::shared_ptr<Bclass> bClass_p, boost::shared_ptr<DclassPool> dClass_p);
2
...

Ist das richtig?

Sorry bitte

von Daniel A. (daniel-a)


Lesenswert?

Ja

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

dominik_ schrieb:
> Noch eine Frage bitte:
>
> ich habe sehr viele funktionen, die so in der Form sind:
>
1
> static void fkt_1(Bclass* bClass_p, DclassPool* dClass_p);
2
> static void fkt_2(Bclass* bClass_p, DclassPool* dClass_p, 
3
> EclassHold*eClassHold);
4
> ....
5
>
>
>
> Das heisst alle Funktionen müssen umgeschrieben werden so ungefähr:
>
1
> static void fkt_1(boost::shared_ptr<Bclass> bClass_p, 
2
> boost::shared_ptr<DclassPool> dClass_p);
3
> ...
4
>
>

Wahrscheinlich eher nein. Wenn die Funktion eine zusätzliche Referenz 
(nicht im C++ Sprachsinn) auf das übergebene Objekt speichern möchte, 
dann braucht die Funktion den shared pointer. Aber auch dann spricht 
wenig dagegen, die shared pointers per const Referenz zu übergeben:
1
    static void fkt_1(
2
        const boost::shared_ptr<Bclass>& bClass_p, 
3
        const boost::shared_ptr<DclassPool>& dClass_p);
4
...

Wenn die Funktion nur eine Referenz auf ein Objekt braucht, und diese 
Referenz nicht optional ist (die Funktion nicht erwartet, dass der 
Pointer 0 sein kann), dann solltest Du es durch eine C++ Referenz 
ersetzen:
1
    static void fkt_1(
2
        Bclass& bClass_p, 
3
        DclassPool& dClass_p);
4
...

Im Idealfall nimmst Du Deine Umbauarbeiten zum Anlass, noch mal das 
Thema const correctness in Deinem C++ Buch nachzuschlagen und dass ggf. 
auch gerade zu ziehen.

mfg Torsten

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.