Hallo ! Folgende Sache beschäftigt mich gerade...dazu das folgende Beispiel: class alt: public MUIWidget { public: void testalt(); } void alt::bufferalt() { printf(...); } class neu: public MUIWidget { public: void testneu(); } void neu:bufferneu() { printf(...); // Aufruf der Funktion bufferalt } Nun jetzt möchte ich gerne in der Funktion bufferneu, die Funktion bufferalt aufrufen. Aber wie mach ich das ?? Mein Compiler ist nur am meckern ?? Kann mir jemand helfen, wie ich das am besten per Software mache ? Mfg Bernd
Bernd T. wrote: > Hallo ! > Folgende Sache beschäftigt mich gerade...dazu das folgende Beispiel: > > class alt: public MUIWidget > { public: > void testalt(); > } > > void alt::bufferalt() > { printf(...); > } > > > class neu: public MUIWidget > { public: > void testneu(); > } > > void neu:bufferneu() > { printf(...); > // Aufruf der Funktion bufferalt > } > > > Nun jetzt möchte ich gerne in der Funktion bufferneu, > die Funktion bufferalt aufrufen. Die kannst du nicht aufrufen, da bufferalt eine nicht statische Memberfunktion ist. Um die aufrufen zu können brauchst du also mindestens ein Objekt vom Typ alt. > > Aber wie mach ich das ?? Dashängt jetzt davon ab, was du wirklich willst und wie die Funktionen tatsächlich aussehen, welche Zusammenhänge in der Funktionalität bestehen und wie die logischen Abhängigkeiten voneinander sind. Szenario 1: *********** In bufferalt gibt es nichts Spezifisches wofür ein alt Objekt gebraucht würde * man könnte die Funktion bufferalt als static Funkion machen und die dann aufrufen
1 | void neu:bufferneu() |
2 | { printf(...); |
3 | |
4 | // Aufruf der static Funktion bufferalt aus der alt Klasse
|
5 | alt::bufferalt(); |
6 | }
|
* man könnte den Inhalt der Funktion bufferalt in eine eigene Funktion auslagern, die zu gar keiner Klasse gehört (eine freistehende Funktion) und diese Funktion dann von bufferalt() und bufferneu() aufrufen
1 | void fnct() |
2 | {
|
3 | }
|
4 | |
5 | void alt::bufferalt() |
6 | {
|
7 | fnct(); |
8 | }
|
9 | |
10 | void neu::bufferneu() |
11 | {
|
12 | fnct(); |
13 | }
|
Szenario 2: *********** Die Funktion bufferalt ist an das alt Objekt gekoppelt und macht auch nur dann Sinn wenn sie eine normale Memberfunktion bleibt. In dem Fall brauchst du natürlich ein alt Objekt, über welches der Aufruf erfolgt.
1 | class alt |
2 | {
|
3 | public:
|
4 | void bufferalt(); |
5 | };
|
6 | |
7 | void alt::bufferalt() |
8 | {
|
9 | ...
|
10 | }
|
11 | |
12 | |
13 | class neu |
14 | {
|
15 | public:
|
16 | void bufferneu(); |
17 | };
|
18 | |
19 | void neu::bufferneu( alt& obj ) |
20 | {
|
21 | obj.bufferalt(); |
22 | }
|
Szenario 3: *********** In Wirklichkeit ist es so, dass es sich bei der Funktionalität um Basisfunktionalität handelt, die sowohl in der Klasse alt als auch in der Klasse neu Sinn macht. Daher würde das auch Sinn machen, dieses in der Klassenhierarchie zum Ausruck zu bringen und beide Klassen von einer zusätzlichen Basisklasse abzuleiten
1 | class alt_neu_basis : public MUIWidget |
2 | {
|
3 | protected:
|
4 | void foo(); |
5 | }
|
6 | |
7 | class alt : public alt_neu_basis |
8 | {
|
9 | public:
|
10 | void bufferalt(); |
11 | };
|
12 | |
13 | void alt::bufferalt() |
14 | {
|
15 | ...
|
16 | foo(); |
17 | }
|
18 | |
19 | class neu : public alt_neu_basis |
20 | {
|
21 | public:
|
22 | void bufferneu(); |
23 | };
|
24 | |
25 | void neu::bufferneu() |
26 | {
|
27 | ...
|
28 | foo(); |
29 | }
|
Szenario 4: *********** Die Funktionalität die in die Basisklasse alt_neu_basis ausgelagert wurde, hat im eigentlichen Sinne nichts mit MUIWidget zu tun. Es handelt sich eher um Funktionalität die an eine MUIWidget Klasse angeklebt werden soll, um das Ziel zu erreichen. Allerdings würde diese Funktionalität auch bei anderen Klassen Sinn machen die nicht von MUIWidget abgeleitet werden. In dem Fall macht man eine neue Klasse, die tatsächlich nur für diese eine Funktionalität zuständig ist und benutzt Mehrfachvererbung um auszudrücken, dass alt zwar ein MUIWidget ist, aber eben auch über diese Zusatzfunktionalität verfügt:
1 | class Zusatz |
2 | {
|
3 | public:
|
4 | void foo(); |
5 | };
|
6 | |
7 | void Zusatz::foo() |
8 | {
|
9 | }
|
10 | |
11 | class alt : public MUIWidget, Zusatz |
12 | {
|
13 | public:
|
14 | void bufferalt(); |
15 | };
|
16 | |
17 | void alt::bufferalt() |
18 | {
|
19 | ....
|
20 | // alt ist zwar vom Typ MUIWidget, aber es ist auch ein
|
21 | // Objekt vom Typ Zusatz. Daher hat alt klarerweise auch
|
22 | // die Funktionalität von Zusatz geerbt und foo()
|
23 | // kann aufgerufen werden
|
24 | foo(); |
25 | }
|
26 | |
27 | class neu : public MUIWidget, Zusatz |
28 | {
|
29 | public:
|
30 | void bufferneu(); |
31 | };
|
32 | |
33 | void neu::bufferalt() |
34 | {
|
35 | ....
|
36 | // neu ist zwar vom Typ MUIWidget, aber es ist auch ein
|
37 | // Objekt vom Typ Zusatz. Daher hat neu klarerweise auch
|
38 | // die Funktionalität von Zusatz geerbt und foo()
|
39 | // kann aufgerufen werden
|
40 | foo(); |
41 | }
|
Im Grunde ist Szenario 4 nur eine Variante von Szenario 1 mit freistehenden Funktionen. Das Ganze allerdings im objektorientierten Gewand. Szenario 5 ********** Das Ganze hat gar nichts mit einer ist-ein Beziehung, also mit Vererbung zu tun, sondern es wäre besser die Funktionalität wiederrum in eine eigene Klasse zu kapseln und sowohl alt aus auch neu bekommen jeweils eine Member Variable dieses neuen Typs zugeteilt. (Also eine hat-ein Beziehung)
1 | class Funktion |
2 | {
|
3 | public:
|
4 | void foo(); |
5 | };
|
6 | |
7 | void Funktion::foo() |
8 | {
|
9 | }
|
10 | |
11 | class alt : public MUIWidget |
12 | {
|
13 | public:
|
14 | void bufferalt(); |
15 | |
16 | private:
|
17 | Funktion m_func; |
18 | };
|
19 | |
20 | void alt::bufferalt() |
21 | {
|
22 | ...
|
23 | m_func.foo(); |
24 | }
|
25 | |
26 | class neu : public MUIWidget |
27 | {
|
28 | public:
|
29 | void bufferneu(); |
30 | |
31 | private:
|
32 | Funktion m_func; |
33 | };
|
34 | |
35 | void neu::bufferneu() |
36 | {
|
37 | ...
|
38 | m_func.foo(); |
39 | }
|
Szenario 6 ********** In Wirklichkeit ist es eher so, dass es zwar eine Klasse alt gibt, aber die Beziehung der Klasse neu so aussieht, dass es eigentlich eine Erweiterung von alt ist und keine Erweiterung von MUIWidget. In dem Fall ist ganz einfach nur deine Klassen- hierarhcie falsch:
1 | class alt : public MUIWidget |
2 | {
|
3 | public:
|
4 | void bufferalt(); |
5 | };
|
6 | |
7 | class neu : public alt |
8 | {
|
9 | public:
|
10 | void bufferneu(); |
11 | }
|
12 | |
13 | void neu::bufferneu() |
14 | {
|
15 | ...
|
16 | bufferalt(); |
17 | }
|
Also: Wer soll nun dein Herzblatt sein? (Wenn ich jetzt noch 30 Sekunden länger darüber nachdenke, welche Fälle du haben könntest, dann fallen mir sicher noch 10 andere Szenarien ein, die bei dir vorliegen könnten und zugehörige C++ Muster wie man dieses Szenario angehen könnte. Zb. waren virtuelle Funktion noch gar nicht im Gespräch.)
WOW !!! Das ist ne Antwort !!! Mein Herzblatt ist "Szenario 5" !! So werde ich weiter verfahren ... D A N K E !!!! Mfg Frank
Und wenn die die Herzblatt-Beziehungen doch zu eng sind, dann bleib bei Freundschaften: http://www.mathematik.uni-marburg.de/~cpp/operatoren/friend_7.html Das ist aber zugegebenermaßen nicht so schön wie Herzblatt Nr. 5 :-) Oliver
Ich sollte auch mal mit C++ anfangen. Das sieht irgendwie cool aus :-) Schönen Abend.
Hallo C++ Programmierer ! Ich habe noch mal ein Szenario das mir Sorgen bereitet! class Funktion { public: void foo(); }; void Funktion::foo() { ... } class alt : public MUIWidget { public: void bufferalt(); private: Funktion testxy; }; void alt::bufferalt() { } Beim Compilieren bekomme ich eine Fehlermeldung. Ich habe bis jetzt nur in class alt: public MUIWidget unter private Funktion testxy deklariert. Compiler Fehler: 'Funktion' is used as a type, but is not defined as a type Kann mir jemand weiterhelfen? Was muss ich ändern? Mfg Bernd T.
Hallo Bernd T, ich habe den Code problemlos compiliert bekommen. Sowohl mit avr-gcc, als auch arm-elf-gcc sowie mit gcc. Kann es sein, dass es nicht die einzige Fehlermeldung ist, die kommt? MfG Mark
Hallo ! Genau so steht es in meinem Programm: class Funktion { public: void foo(); }; void Funktion::foo() {... } class alt : public MUIWidget { private: Funktion testxy; public: virtual void TestButton() { testxy.foo(); }; } Fehlermedlung vom Compiler: 'Funktion' is used as a type, but is not defined as a type `testxy' undeclared (first use this function) Each undeclared identifier is reported only once for each function it appears in.) So, hast Du dafür jetzt auch noch eine Antwort ??? Gruss Bernd T
hallo, poste am besten einmal den compiler-aufruf, ich glaube, da läuft was verkehrt. bye kosmo
Genau irgendwas läuft auch verkehrt! Ich bin der Meinung der Quelltext ist in Ordnung! Der Fehler muss woanders liegen... Folgender Hinweis den ich hier noch nicht erwähnt habe, vielleicht gibt dieses Aufschluss ! Ich habe beide Funktion getrennt voneinander, damit meine ich das zwei Headerdatein mit deren Quelltext zusammengefügt werden sollen. Headerdatei I [test.h] class Funktion { public: void foo(); }; Im Quelltext von Headerdatei I steht die Funktion! [test.cpp] void Funktion::foo() {... } *********************************************************************** Headerdatei II [lamp.h] class alt : public MUIWidget { private: Funktion testxy; public: virtual void TestButton() { testxy.foo(); }; } Kann dies eine Ursache sein?
hallo, na wenn du dem compiler bei der verwendung der klasse "Funktion" keinen hinweis gibtst, wo er nach deren beschreibung (deklaration) suchen soll, kann das nicht gehen. #include "test.h" am beginn der zweiten header-datei sollte erst einmal helfen. bye kosmo
Sorry, dass ist der Fehler leider nicht !! Danke aber trotzdem für die Idee..!
Hallo Headerdatei II [lamp.h]
1 | class alt : public MUIWidget |
2 | {
|
3 | private:
|
4 | Funktion testxy; |
5 | |
6 | public:
|
7 | virtual void TestButton() |
8 | {
|
9 | testxy.foo(); |
10 | };
|
11 | }
|
Hier sollte doch das Semikolon in in die nächste Zeile.
1 | }; |
2 | }
|
zu
1 | }
|
2 | }; |
Mfg Marius
Hi ! Das habe ich korrigiert... Es hat sich allerdings nichts geändert... Unabhängig von den Routinen, sobald ich nur schreibe Funktion testxy; kommt => 'Funktion' is used as a type, but is not defined as a type. Ich kann " Funktion testxy; " nur in die test.cpp mit nehmen. Sobald ich diese in der test.h deklariere meckert er auch !! Sorry, ich brauch nen BREAK !! Bis später mal Danke für Eure Hilfen !!!
hallo, du brauchst keine pause. du müsstest lediglich endlich ein aussagekräftiges beispiel posten, damit nicht laufend korrekturen von dir notwendig werden. das kann hier gerne inline passieren. aber so wie derzeit, wenn ständig noch zusätzliche info's bekannt werden, dauert es halt etwas. vll in diesem zusammenhang wichtig ist auch der komplette compiler-output. thx, viel erfolg bye kosmo
> Hallo ! > Genau so steht es in meinem Programm: > > class Funktion > { > public: > void foo(); > }; > > void Funktion::foo() > {... > } Kein Wunder, daß dann eine Fehlermeldung kommt. Die drei Punkte dürfen da nicht stehen. Oder war's vielleicht doch nicht "genau so"? Poste doch bitte nur Code, der tatsächlich die Fehlermeldung prozudiert hat und nicht irgendwas, was "genau so" ist.
Hallo ! Ich habe den Quellcode im Anhang beigelegt! Anhand der roten Textzeilen erkannt man die relevanten Stellen, welche die Fehlermeldung CUIMbt.h:32: error: 'Funktion' is used as a type, but is not defined as a type hervorrufen! Ich hoffe es gibt Euch die Möglichkeit mir weiterzuhelfen! Mfg Bernd T.
> Ich habe den Quellcode im Anhang beigelegt!
Als Word-File?!?
Wie heißen die Dateien denn? Heißt die auf der dritten Seite
MUIWidget.h? Wenn nicht, kann das ja nicht gehen. Wo ist denn innerhalb
der Datei auf der ersten Seite sonst der Header inkludiert, der die
Klasse Funktion definiert?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.