[c/c++] Spaghetti code?

Hannnibal

Admiral Special
Mitglied seit
27.03.2003
Beiträge
1.804
Renomée
5
Moin,

ich hab das problem das eine member variable einer klasse erst "int" ist und im späteren Programmverlauf "double" seien muß...
1. Möglichkeit die mir in den sinn kam: Klasse ableiten...member überladen...
Klappte aber irgendwie nicht :(.
2. Eine Status variable welche angibt was meine variable gerade ist (integer oder double)
Variable wird void zeiger...
Das ist dabei rausgekommen *chatt*
In der Header:
Code:
protected:
	bool doubleGr;
 
 	void* ptrGroesse;
dazugehörigen CPP
Code:
MessDatum::MessDatum(double gr, float gw)  {
	ptrGroesse=&gr;
	gewicht=gw;
	doubleGr=false;
}
MessDatum::MessDatum(double gr, float gw)  {
	ptrGroesse=&gr;
	gewicht=gw;
	doubleGr=true;
Im spätern Programmcode...
Lesender zugriff
Code:
	if (doubleGr) double groesse = *((double*)ptrGroesse);
	else int groesse = *((int*)ptrGroesse);
Für schreiben denke ich mir auch noch was aus...
Funktioniert das überhaupt (zuverlässig) so?
Wann gehen mir die normalen variablen kaputt? (also zb das übergebene gr im constructor...)
Gibt es ein besser Lösung...?
Wie sieht die bug gefahr dabei aus? Noch vertretbar oder absoluter murks...?
Sollte ich lieber float anstatt double nehmen? (integer 32bit/ double 64) oder ist das egal...
mfg
 
Zuletzt bearbeitet:
Spontan fällt mir der Einsatz von Templates ein, aber das hilft Dir ja auch nicht, da Du innerhalb einer Klasse den Typ am lebenden Objekt ändern willst. *chatt*
Aber klassisch kann so ein Problem mit union und einem Tag gelöst werden. Ist ähnlich wie Deine Lösung, aber etwas sauberer und es wird auf Pointer verzichtet:

Code:
class use_var {
public:
  enum eTag { USE_INT, USE_DOUBLE };

private:
  union { int i; double d; };
  eTag tag;
  
public:
  eTag get_tag() { return tag };

  use_var(int ii)    { i = ii; tag = USE_INT; } 
  use_var(double dd) { d = dd; tag = USE_DOUBLE; } 
  int& get_int()     { return i; }
  double& get_double()  { return d; }
};

Benützung:
Code:
  use_var val(0.5);  
  ...
  if (val.get_tag() == USE_DOUBLE)
      double groesse = val.get_double();
  else
      int groesse = val.get_int();
  ...
Es lässt sich bei get_xxx() noch ein Check einbauen, welcher sicherstellt, daß zum Type der richtige Tag eingestellt ist.

So sinngemäß ist das im Bjarne Stroustrup beschrieben.

Ciao,
Ray
 
Zuletzt bearbeitet:
Moin,

super tip :), ist wirklich schöner diese methode...
Allerdings ist ein problem geblieben.
Die Variable groesse wird im if else block declariert....leider meckert der compiler das ihm die variable im weiteren programmablauf unbekannt vorkommt :(.

Da muß ich wohl doch wieder auf pionter umschwenken :(.
Oder gibt es die möglichkeit eine int groesse außerhalb des blocks zu deklarieren und im block umzupolen?

mfg
 
Also so richtig verstehe ich dein Problem noch nicht. Du kannst doch einem double einfach ein int-Wert zuweisen. *noahnung*
 
Moin Puck,

Die groesse wird aber später im bereich von 1.xx-2.xx leigen (normiert sogar nur von 0.xx-1).
da macht int zuweisung nicht richtig spass...
Ich werde es so machen das in dem zweig wo ich festelle ob es eine double oder int ist dierekt mit dem restlichen prozeduren weiter mache...das verdoppelt zwar den code, aber was solls :).
Es kann durchaus sein das ich es mir komplizierter mache als nötig :], aber nach dem conzept wird jetzt implementiert...*chatt*
mfg
 
Zuletzt bearbeitet:
hm ich denk auch, einfach ein double nehmen und wenns die int sein soll ein int drauf casten
also quasi die kommastellen abschneiden
 
Moin,

es geht darum das man in dem programm gezielt mit integer rechnet und später auf Floating piont umstellt, es sollen die Mess Fehler bzw Fehler die aus der datenhaltung resultieren dargestellt werden.
So klappt des ganz gut... :)

mfg
 
Das kannst du doch schon mit C recht angenehm per union lösen.

Schöner wäre natürlich, wenn du darum eine Klasse mit überladenem cast bastelst - per Befehl kannst du dann umschalten, dass er intern statt integer doch double nehmen soll, nach 'draußen' ändert sich ja dann nix.

Oder eben das einfachste - du macht da wo du integer brauchst immer einen cast nach integer.

EDIT

@Ray

Hast meine Lösung natürlich schon gepostet :P. Allerdings fehlt noch der cast ;).

Also ungefähr so hier:

Code:
class variant
{
  public:
    operator int();
    operator double();

    int operator=(variant value);
    int operator=(int value);
    int operator=(double value);

    void switch_int();
    void switch_double();
};


So könnte man zB. auch komplett den Variant implementieren, auf dem die VB-Extremisten immer so rumreiten.
 
Zuletzt bearbeitet:
Zurück
Oben Unten