enum aus Klasse in anderer Klasse davor benutzen

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
Spinoza
Beiträge: 23
Registriert: 4. März 2011 01:07

enum aus Klasse in anderer Klasse davor benutzen

Beitrag von Spinoza »

Guten Tag zusammen,
gegeben folgende Situation:

Code: Alles auswählen

class A {
  void func(B::EnumType x);
};

class B {
  enum EnumType {etOne, etTwo};
  A aInstance;
};
EnumType sollte aus Konsistenz- und Übersichtlichkeitsgründen im namespace von B bleiben. Gleichzeitig wird es jedoch in A verwendet. Klasse A kann ich nicht einfach unter B setzen, da B einen Member vom Typ A hat. Welche Möglichkeiten gibt's das aufzulösen?
Forward-Deklaration von A und Umwandlung von aInstance in einen Zeiger auf A ist mir bekannt. Möchte ich aber tunlichst vermeiden, da es sich für aInstance "unnatürlich anfühlen würde", sie in B als Zeiger zu führen. (Ist eine immanente aber komplexe Eigenschaft von B, die zur Übersichtlichkeit in eine eigene Klasse A ausgelagert wurde.) Abgesehen von der entstehenden Inkonsistenz im Projekt - dann müsste ich ja alles bis auf primitive Datentypen als Zeiger führen.
Mir fiele noch ein, sämtliche Enums in dem Projekt in einen großen Namespace ganz am Anfang zu packen, ist aber eher schlechter Stil, würde ich sagen.

Über Vorschläge würde ich mich sehr freuen.
Gruß,
Spinoza
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Re: enum aus Klasse in anderer Klasse davor benutzen

Beitrag von solarix »

hmm..

So ein richtiger Knaller fällt mir auch nicht ein, aber
Spinoza hat geschrieben:..eine immanente aber komplexe Eigenschaft von B, die zur Übersichtlichkeit in eine eigene Klasse A ausgelagert wurde..
klingt für mich z.B. nach

Code: Alles auswählen

class B {
  enum EnumType {etOne, etTwo};
  class A {
    void func(EnumType x);
  };

private:
  A aInstance;
};
Sollte "A" allerdings im public-Interface von "B" benötigt werden, so wird das vermutlich recht schnell unübersichtlich.. eine get-Methode für "aInstance" sähe ja nicht wirklich schick aus:

Code: Alles auswählen

B::A B::getA()
{
  return aInstance;
}
Aber zu den beiden Varianten "Pointer-mit-Forward-Decl" und "Enum-Auslagern": Beide klingen für mich ebenfalls nach einer akzeptablen Lösung. Ehrlich gesagt, wäre mein erster Gedanke beim Anblick der Zeile "aInstance->doXy()" von einem Teamkollegen wahrscheinlich eher nicht "Mein Gott.. da hat er doch tatsächlich eine immanente aber komplexe Eigenschaft von B ALS POINTER deklariert!!".

Ich würde vermutlich eher denken: "hat er an den "Deep-Copy" gedacht..?". Auch kann ich nicht erkennen, warum du dann "alles bis auf primitive Datentypen als Zeiger führen" oder "sämtliche Enum des Projektes" auslagern müsstest. Das wären ja nicht "alle" enums, sondern nur die gemeinsamen enums von A und B.

Falls du keine perfekte Lösung findest: bleib in C++ pragmatisch.. Für Philosophen gibt es andere Programmiersprachen :P
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: enum aus Klasse in anderer Klasse davor benutzen

Beitrag von franzf »

Spinoza hat geschrieben:Ist eine immanente aber komplexe Eigenschaft von B, die zur Übersichtlichkeit in eine eigene Klasse A ausgelagert wurde.
"Ausgelagert" heißt für mich "Wären eigentlich alles private Member". Somit sollte A kein Bestandteil deiner API sein.
-> A wird ein "struct" im private Teil von B. Fertig.
(Meine Meinung ;) und scheinbar auch die von Solarix)
Spinoza
Beiträge: 23
Registriert: 4. März 2011 01:07

Re: enum aus Klasse in anderer Klasse davor benutzen

Beitrag von Spinoza »

franzf hat geschrieben:
Spinoza hat geschrieben:Ist eine immanente aber komplexe Eigenschaft von B, die zur Übersichtlichkeit in eine eigene Klasse A ausgelagert wurde.
"Ausgelagert" heißt für mich "Wären eigentlich alles private Member". Somit sollte A kein Bestandteil deiner API sein.
-> A wird ein "struct" im private Teil von B. Fertig.
Naja, bevor um den heißen Brei herumgeredet wird: B ist eine Achse eines Plots. A ist die "range", also das dargestellte Intervall (Obergrenze, Untergrenze). Das dargestellte Intervall ist selbstverständlich etwas, das stark mit der Achse zusammenhängt. Dennoch ist A im public interface von B, schließlich muss das von der Achse dargestellte Intervall über entsprechende Methoden von A veränderbar sein.
Dazu kommt, dass ranges (A) auch ausserhalb der Achse benutzt/erzeugt werden können, um dann z.B. sowas wie MyAxis.setRange(newRange); schreiben zu können, wobei newRange eine achsenunabhängige Instanz von A ist, welche schließlich die Range der MyAxis überschreibt.
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Re: enum aus Klasse in anderer Klasse davor benutzen

Beitrag von solarix »

Naja.. ich weiss nicht ob man das als "selbstverständlich" bezeichnen kann.. wir haben schon mehrere Charts/Plots implementiert und dabei jeweils die "Renderer"-Klassen (deine "MyAxis") von der (Chart-)Konfiguration getrennt. Bei uns beziehen also alle "Renderer"-Klassen (Y-Achsen, T-Achse sowie "Plot-Area") die Einstellungen aus der zum Chart gehörenden Konfiguration. Damit übernimmt die Chart-Konfiguration die Rolle eines "Datenbackends", oder von mir aus ein "Model"/"View"-Verhältnis.

Damit können wir z.B. die gesammte Chart-Konfiguration neu Laden (aus Datei, Datenbank oder User-Dialog) und die "Renderer"-Klassen kriegen via Signals mit "hey, die Konfig wurde geändert, neu Berechnen/Rendern".

Lange Rede kurzer Sinn: Gerade in diesem Fall haben wir uns immer für die Pointer-Variante entschieden (Analog zum Model-Pointer bei einer Model-View-Architektur).

hth!
Antworten