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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren