C/C++: Probleme mit Funktionspointern

OP #5469670
Lesenswert?
• ▲
▼
Hi,
ich habe da ein Problem beim verwenden von Funktionspointern bei der 
Übergabe bei einer Klasseninitalisierung. Ich habe mich hierbei an den 
zweiten Forenbeitrag in diesem Link gehalten: 
https://www.spieleprogrammierer.de/18-c-cplusplus-csharp-java-und-andere-programmiersprachen/6621-funktionszeiger-funktionen-als-parameter/


Folgendes Szenario:
Ich habe eine Klasse "Class":
1
namespace Namespace
2
{
3
    class Class    
4
    {
5
    private:
6
        void(*FuncPtr)() = NULL;
7
    public:
8
        Class()
9
        {}
10

11
        Class(int value, void(*funcPtr)())
12
        {
13
            FuncPtr = funcPtr;
14
        }
15
    /*****/
16
    };
17
}
Die Funktion wird so definiert und die Klasse so initalisiert:
1
void Funktion()
2
{ /*****/ }
3

4
int foo;
5

6
Namespace::Class Klasse;
7

8
void setup()
9
{
10
    Klasse = Class(foo, void (*Funktion)())  /<<<<Fehler
11
    /****/
12
}
Hier tauchen zwei Fehler auf, einer kommt vom Visual Studio, das 
unterkingelt mir das Rückgabe-void mit dem Fehlertext:
"der Ausdruck vor den Klammern des sichtbaren Aufrufs muss einen 
Funktionstyp (pointer-to-) aufweisen"

Der Compiler meldet mir folgenden Fehler:
"void value not ignored as it ought to be"

Wenn ich die void durch int ersetze, und natürlich für in die Funktion 
ein return 0 einbaue, erhalte ich vom Visual Studio die gleiche 
Fehlermeldung, der Compiler meldet allerdings:
"expression cannot be used as a function".

Was mache ich hier falsch?
(Firma: Torrox.de) #5469696
Lesenswert?
• ▲
▼
Matthias S. schrieb:

Hallo Matthias,

>         void(*FuncPtr)() = NULL;

diese Art der Initialisierung gibt es erst seit C++11.


>     Klasse = Class(foo, void (*Funktion)())  /<<<<Fehler

Du must hier zwischen der Deklaration eines Parameters von Typen: "Ist 
Funktion, die keine Argumente nimmt und nix zurück gibt" und der 
Übergabe eins konkreten Werts beim Aufruf unterscheiden. Der erst 
Parameter ist von Typen int. Dort übergibst Du doch auch einfach einen 
int:
1
    Klasse = Class(foo, Funktion);
Gast #5469932
Lesenswert?
• ▲
▼
Wenn man Funktionspointer konsequent weg-typedeft, dann steht die 
ekelhafte Syntax nur an einer Stelle und der Rest des Programms bleibt 
davon verschont:
1
class Class
2
{
3
public:
4
    typedef void (*tVoidFunc)();
5
    Class(int value, tVoidFunc fp) : m_fp(fp) { }
6
private:
7
    tVoidFunc m_fp;
8
};
9

10
void myfunc(){}
11

12
int main(){
13
    Class c(23, myfunc);
14
    return 0;
15
}
#5470115
Lesenswert?
• ▲
▼
Rolf M. schrieb:
> Vincent H. schrieb:
>> Die leserlichste Form einer Typdefinition eines Funktionszeigers bekommt
>> man imho via
>> using VoidFp = auto (*)() -> void;
>
> Ist das ironisch gemein? Da ist ja gegenüber einer normalen
> Funktionsdefinition alles verdreht.

Nein das mein ich ernst. Ich schreib gern C++ Code aber der Purist in 
mir sieht Rückgabewerte lieber am Ende einer Definition.
1
// Go
2
func add(x int, y int) int {
3
  return x + y
4
}
5

6
// Rust
7
fn five() -> i32 {
8
    5
9
}
Gast #5470420
Lesenswert?
• ▲
▼
Matthias S. schrieb:
> Namespace::Class Klasse;
>
> void setup()
> {
>     Klasse = Class(foo, void (*Funktion)())

Dir ist klar, dass du hier erst eine "leere" Instanz anlegst, und dann 
in der main() eine temporäre zweite Instanz, und die über die erste 
kopierst? Einfacher (und effizienter) wäre so:
1
Namespace::Class Klasse (foo, Funktion);
2
int main () {
3
...
4
}
So brauchst du auch den Standard Konstruktor nicht mehr.
Die Instanz einer Klasse nennt man übrigens Objekt, und nicht Klasse...

Matthias S. schrieb:
> void(*FuncPtr)() = NULL;

NULL ist veraltet, bitte nullptr nutzen...
OP #5470918
Lesenswert?
• ▲
▼
Tom schrieb:
> Wenn man Funktionspointer konsequent weg-typedeft, dann steht die
> ekelhafte Syntax nur an einer Stelle und der Rest des Programms bleibt
> davon verschont:
>
1
> class Class
2
> {
3
> public:
4
>     typedef void (*tVoidFunc)();
5
>     Class(int value, tVoidFunc fp) : m_fp(fp) { }
6
> private:
7
>     tVoidFunc m_fp;
8
> };
9
> 
10
> void myfunc(){}
11
> 
12
> int main(){
13
>     Class c(23, myfunc);
14
>     return 0;
15
> }
16
>

Danke.
Jetzt habe ich verstanden, warum bei der Verwendung von typdef immer von 
"Vereinfachung" gesprochen wird.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.