Forum: PC-Programmierung in C++ Aus eine Mehrfachvererbung Object erzeugen


von Saheb (Gast)


Lesenswert?

Hallo zusammen,
bestehende Code:

1
class cA
2
{
3
public:
4
typedef enum cAType{enUndefAType,enTypeA01,enTypeA02,enTypeA03...}t_enTypeA
5
cA(t_enTypeA enTypeA)
6
{
7
....
8
}
9
...
10
};
dann
1
class cB
2
{
3
public:
4
typedef enum cBType{enUndefBType,enTypeB01,enTypeB02,enTypeB03...}t_enTypeB
5
cB(t_enTypeB enTypeB)
6
{
7
....
8
}
9
...
10
};

und
1
class cD:public cA, public cB
2
{
3
public:
4
cD(t_enTypeA enTypeA = enTypeA01, t_enTypeB enTypeB = enTypeB01,t_enTypeC enTypeC = enTypeC01)
5
{
6
....
7
}
8
 
9
};
10
11
Problem ist: Wenn ich einen Object von Type cD erzeuge:
12
13
cD *mPointer_cD = new CD();
14
dann ist das Object mPointer_cD mit folgende Enumeration Type (enTypeA01,enTypeB01,enTypeC01) initialisiert und das möchte ich nicht.
15
16
17
Idee wäre Objecte von Type cD flexible zu erzeugen.
18
Das heisst es muss direkt beim Erzeugung des Objects, die Initialisierung folgen.
19
Idee: Wie mache ich am besten mit minimalen Aufwand?
20
21
Danke

von Keiner N. (nichtgast)


Lesenswert?

Am Besten befragst du deine Rubberduck was an deinem Ansatz 
grundsätzlich falsch ist.

https://en.wikipedia.org/wiki/Rubber_duck_debugging


Beschreib mal, was du erreichen willst. Irgend wie scheint mir dein 
ganzer Ansatz in die falsche Richtung zu gehen. Besser wäre in deinem 
Fall eher Komposition statt Vererbung

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Wie wärs damit, einfach die gewünschten Werte zu übergeben?
1
cD *mPointer_cD = new CD(enTypeA02, enTypeB02);
Und warum so kompliziert mit typedef, warum nicht einfach so:
1
enum enTypeA{enUndefAType,enTypeA01,enTypeA02,enTypeA03...};
Und ich hoffe diese super kryptischen Enum-Namen sind nicht die 
Echten...

von Rolf M. (rmagnus)


Lesenswert?

Saheb schrieb:
> Problem ist: Wenn ich einen Object von Type cD erzeuge:
>
> cD *mPointer_cD = new CD();
> dann ist das Object mPointer_cD mit folgende Enumeration Type
> (enTypeA01,enTypeB01,enTypeC01) initialisiert und das möchte ich nicht.

Aber du hast doch weiter oben in deinem Code explizit hingeschrieben, 
dass du genau das möchtest:
1
cD(t_enTypeA enTypeA = enTypeA01, t_enTypeB enTypeB = enTypeB01,t_enTypeC 
2
enTypeC = enTypeC01)

> Idee: Wie mache ich am besten mit minimalen Aufwand?

Das ist keine Idee, sondern eine Frage. Die Antwort wäre: Wenn du keine 
Default-Initialisierung willst, dann schreibe auch keine hin.

von Saheb (Gast)


Lesenswert?

Hallo zusammen,


ich glaube wir reden an einander vorbei.

Rolf M. schrieb:
> Die Antwort wäre: Wenn du keine
> Default-Initialisierung willst, dann schreibe auch keine hin

@Wenn ich das mache dann bekomme ich folgende Fehlermeldung:
1
Error   C2512   'cD': no appropriate default constructor available

Hintergrund:
Es handelt sich um einen geerbte Project, der mindesten 10 Jahre alt.
Ich kann auch so machen:
1
cD *mPointer_cD = new CD(cA::enTypeA02, cB::enUndefBType, cD::enTypeC03);
Problem: Dieses Aufruf ist nicht zentral wie der Default Konstruktor.
Gibt es eine andere Möglichkeit diese bessere zu lösen.

Danke

von Oliver S. (oliverso)


Lesenswert?

Saheb schrieb:
> Problem: Dieses Aufruf ist nicht zentral wie der Default Konstruktor.
> Gibt es eine andere Möglichkeit diese bessere zu lösen.

Nein

Oliver

von Rolf M. (rmagnus)


Lesenswert?

Saheb schrieb:
> @Wenn ich das mache dann bekomme ich folgende Fehlermeldung:
> Error C2512   'cD': no appropriate default constructor available

In welcher Zeile? In dem obigen Code ist nirgends ein Grund zu erkennen, 
warum ein Default-Konstruktor nötig wäre.

> Hintergrund:
> Es handelt sich um einen geerbte Project, der mindesten 10 Jahre alt.
> Ich kann auch so machen:
> cD *mPointer_cD = new CD(cA::enTypeA02, cB::enUndefBType,
> cD::enTypeC03);
> Problem: Dieses Aufruf ist nicht zentral wie der Default Konstruktor.
> Gibt es eine andere Möglichkeit diese bessere zu lösen.

Hmm, ich verstehe nicht wirklich, was du genau suchst. Soll deine Klasse 
jetzt default-inititalisierbar sein oder nicht?
Wenn nein, dann ergibt sich die Frage, warum dein Compiler trotzdem 
einen Default-Konstruktor will.
Wenn ja, wo soll denn der Wert herkommen, wenn du keinen angeben willst?

von Oliver S. (oliverso)


Lesenswert?

Es muß ja irgend einen Grund haben, warum  der Konstruktor so aussieht, 
wie er aussieht.

UNd wenn der diese Signatur hat:
1
cD(t_enTypeA enTypeA = enTypeA01, t_enTypeB enTypeB = enTypeB01,t_enTypeC enTypeC = enTypeC01)

dann könnte es sein, daß es erforderlich sit, enTypeA, enTypeB und 
enTypeC mit sinnvollen Werten vorzubesetzen, weil ansonsten irgend was 
da drin nicht funktioniert.

Wenn dir die defalt-Parameter nicht gefallen, dann bleiben zwei 
Lösungen:

a) du übergibst andere Parameter im Konstruktoraufruf:
1
cD *mPointer_cD = new CD(cA::enTypeA02, cB::enUndefBType, cD::enTypeC03);

b) du änderst das vorhandene Projekt, und schreibst dir selber einen 
Konstruktor, der das macht, was du möchtest.

Oliver

von Saheb (Gast)


Lesenswert?

Oliver S. schrieb:
> Wenn dir die defalt-Parameter nicht gefallen, dann bleiben zwei
> Lösungen:
>
> a) du übergibst andere Parameter im Konstruktoraufruf:cD *mPointer_cD =
> new CD(cA::enTypeA02, cB::enUndefBType, cD::enTypeC03);
> b) du änderst das vorhandene Projekt, und schreibst dir selber einen
> Konstruktor, der das macht, was du möchtest.

Die erste variante habe ich genommen und so kann ich auch das Projekt 
problemlos einen Build erstellen.

Problem ist:
In dem Projekt selber gibt es sehr viele Abhängigkeiten und irgendwann 
im Laufe das Programm ist das Object
1
cD= NULL

von Oliver S. (oliverso)


Lesenswert?

Tja, Debugger anwerfen, und suchen.

Oliver

von c-hater (Gast)


Lesenswert?

Keiner N. schrieb:

> Irgend wie scheint mir dein
> ganzer Ansatz in die falsche Richtung zu gehen.

Genau. Mehrfachvererbung ist an sich schmutzig, denn es widerspricht 
eigentlich den Grundkonzepten der OO-Programmierung.

Blöderweise ist es aber in der Praxis oft erforderlich, 
Mehrfachvererbung oder etwas funktional ähnliches zu benutzen, wenn man 
identischen Code nicht an 'zich verschiedenen Stellen in verschiedenen 
Klassenhierarchien pflegen möchte.

> Besser wäre in deinem
> Fall eher Komposition statt Vererbung

So isses. Und dank Interfaces kann man das sogar soweit abtarnen, dass 
es zumindest "von außen" weitestgehend so aussieht, als hätte die Klasse 
die Fähigkeiten mehrerer Vorfahr-Klassen geerbt.

Natürlich: zumindest in der Klasse, die die Hierarchien zusammenführt, 
hat man deutlich mehr Schreib- und Verwaltungsarbeit. Trotzdem würde ich 
diesen Ansatz jederzeit gegenüber der Mehrfachvererbung bevorzugen.

von Saheb (Gast)


Lesenswert?

und wenn ich das Design der SW ändere und dafür der Entwurfmuster 
"Composite" anwende:

Wie sollen dann die Klassen aussehen? bzw wie soll dann der Entwurf 
sein?

Danke

von Saheb (Gast)


Angehängte Dateien:

Lesenswert?

Wenn ich folgende Klassen Diagramm habe (Seh bitte Anhang 
"KlassenDiagramm").
Das entspricht meinen IstStand.
Wie sollen diese Klassendiagramm zu den Kompositum 
(Entwurfsmuster)anpassen?

https://de.wikipedia.org/wiki/Kompositum_(Entwurfsmuster)

Das passt irgendwie nicht.

Sorry für diese Frage aber ich komme irgendwie nicht weiter.
Danke

von Saheb (Gast)


Lesenswert?

In dem jetzigen Stand lässt sich die SW nicht erweitern.
Eine Redesign ist nötig.

In der SW wird eine neue Erweiterung geben und in der jetzigen SW Design 
ist das unmöglich.

Was ich jetzt gerne hätte, ist von der jetzigen gekoppelten Abhängigkeit 
wegzugehen.

Wie es oben beschrieben ist, class D erbt von A,B und C (Also eine 
Mehrfachvererbung).Ich möchte diese durch eine Composite Entwurfmuster 
ersetzen.
Meine Frage wie tue ich das:(Nur das Klassendiagramm reicht mir).

Danke

von Saheb (Gast)


Lesenswert?

Hallo zusammen,


Wenn ich so habe:
1
cD *mPointer_cD = new cD[3];
aber wenn ich so was habe:
1
cD *mPointer_cD = new CD(cA::enTypeA02, cB::enUndefBType, cD::enTypeC03);
wie schreibe ich eine Array von Pointer?
Danke

von CPP_ (Gast)


Lesenswert?

Saheb schrieb:
> wie schreibe ich eine Array von Pointer?
1
cD *mPointer_cD = new CD[3]{CD(cA::enTypeA02, cB::enUndefBType, cD::enTypeC03)....};

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.