mikrocontroller.net

Forum: Compiler & IDEs Funktionsufruf zwischen 2 Klassen


Autor: Bernd T. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
    void neu:bufferneu()
    { printf(...);

      // Aufruf der static Funktion bufferalt aus der alt Klasse
      alt::bufferalt();
    }

  * 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
    void fnct()
    {
    }

    void alt::bufferalt()
    {
      fnct();
    }

    void neu::bufferneu()
    {
      fnct();
    }

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.
class alt
{
  public:
    void bufferalt();
};

void alt::bufferalt()
{
  ...
}


class neu
{
  public:
    void bufferneu();
};

void neu::bufferneu( alt& obj )
{
  obj.bufferalt();
}

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
class alt_neu_basis : public MUIWidget
{
  protected:
    void foo();
}

class alt : public alt_neu_basis
{
  public:
    void bufferalt();
};

void alt::bufferalt()
{
  ...
  foo();
}

class neu : public alt_neu_basis
{
  public:
    void bufferneu();
};

void neu::bufferneu()
{
  ...
  foo();
}

  

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
class Zusatz
{
  public:
    void foo();
};

void Zusatz::foo()
{
}

class alt : public MUIWidget, Zusatz
{
  public:
    void bufferalt();
};

void alt::bufferalt()
{
  ....
  // alt ist zwar vom Typ MUIWidget, aber es ist auch ein
  // Objekt vom Typ Zusatz. Daher hat alt klarerweise auch
  // die Funktionalität von Zusatz geerbt und foo()
  // kann aufgerufen werden
  foo();
}

class neu : public MUIWidget, Zusatz
{
  public:
    void bufferneu();
};

void neu::bufferalt()
{
  ....
  // neu ist zwar vom Typ MUIWidget, aber es ist auch ein
  // Objekt vom Typ Zusatz. Daher hat neu klarerweise auch
  // die Funktionalität von Zusatz geerbt und foo()
  // kann aufgerufen werden
  foo();
}

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)
class Funktion
{
  public:
    void foo();
};

void Funktion::foo()
{
}

class alt : public MUIWidget
{
  public:
    void bufferalt();

  private:
    Funktion m_func;
};

void alt::bufferalt()
{
  ...
  m_func.foo();
}

class neu : public MUIWidget
{
  public:
    void bufferneu();

  private:
    Funktion m_func;
};

void neu::bufferneu()
{
  ...
  m_func.foo();
}

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:
class alt : public MUIWidget
{
  public:
    void bufferalt();
};

class neu : public alt
{
  public:
    void bufferneu();
}

void neu::bufferneu()
{
  ...
  bufferalt();
}


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

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
WOW !!!
Das ist ne Antwort !!!

Mein Herzblatt ist "Szenario 5" !!

So werde ich weiter verfahren ...


D A N K E !!!!

Mfg Frank

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wenn die die Herzblatt-Beziehungen doch zu eng sind, dann bleib bei 
Freundschaften:

http://www.mathematik.uni-marburg.de/~cpp/operator...


Das ist aber zugegebenermaßen nicht so schön wie Herzblatt Nr. 5 :-)

Oliver

Autor: Stefan (Gast)
Datum:

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

Schönen Abend.

Autor: Bernd T. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Mark .. (mork)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Bernd T. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: kosmonaut_pirx (Gast)
Datum:

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

Autor: Bernd T. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: kosmonaut_pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Bernd T. (Gast)
Datum:

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

Autor: marius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Headerdatei II [lamp.h]
class alt : public MUIWidget
{
private:
   Funktion testxy;

public:
   virtual void TestButton()
  {
      testxy.foo();
  };
}

Hier sollte doch das Semikolon in in die nächste Zeile.
   };
}
zu
   }
};

Mfg Marius

Autor: Bernd T. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 !!!

Autor: kosmonaut_pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.


Autor: Bernd T. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?


Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.