Forum: Compiler & IDEs Funktionsufruf zwischen 2 Klassen


von Bernd T. (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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
}

  

von Karl H. (kbuchegg)


Lesenswert?

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.)

von Frank (Gast)


Lesenswert?

WOW !!!
Das ist ne Antwort !!!

Mein Herzblatt ist "Szenario 5" !!

So werde ich weiter verfahren ...


D A N K E !!!!

Mfg Frank

von Oliver (Gast)


Lesenswert?

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

von Stefan (Gast)


Lesenswert?

Ich sollte auch mal mit C++ anfangen. Das sieht irgendwie cool aus :-)

Schönen Abend.

von Bernd T. (Gast)


Lesenswert?

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.

von Mark .. (mork)


Lesenswert?

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

von Bernd T. (Gast)


Lesenswert?

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

von kosmonaut_pirx (Gast)


Lesenswert?

hallo,
poste am besten einmal den compiler-aufruf, ich glaube, da läuft was 
verkehrt.
bye kosmo

von Bernd T. (Gast)


Lesenswert?

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?

von kosmonaut_pirx (Gast)


Lesenswert?

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

von Bernd T. (Gast)


Lesenswert?

Sorry, dass ist der Fehler leider nicht !!
Danke aber trotzdem für die Idee..!

von marius (Gast)


Lesenswert?

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

von Bernd T. (Gast)


Lesenswert?

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 !!!

von kosmonaut_pirx (Gast)


Lesenswert?

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

von Rolf Magnus (Gast)


Lesenswert?

> 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.


von Bernd T. (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.