Home c++ Callback Functions in C++

Callback Functions in C++

Author

Date

Category

I would like to make sure that I write everything right and adequately. Please tell me what errors are present in the code and preferably tips, how to make it right.

# include & lt; iostream & gt;
Using Namespace STD;
Class Point {
Private:
  INT XPOS, YPOS;
Public:
  Point (int x, int y): xpos (x), ypos (y) {}
  Point (): Point (0,0) {}
  int x () {Return XPOS; }
  int y () {Return YPOS; }
  void setx (int x) {this- & gt; xpos = x; }
  Void Setey (int y) {this- & gt; ypos = y; }
};
Class Square {
Private:
  Void (* Callbackfunc) (Point Point);
  Point Posleftup;
Public:
  Square () {}
  Square (POS): Posleftup (POS) {}
  // Imitation of the movement of the square on the window
  Void Move (Char Key) {
    if (Key == 'A')
      posleftup.setx (posleftup.x () - 2);
    ELSE if (key == 'd')
      posleftup.setx (posleftup.x () + 2);
    ELSE if (key == 'w')
      posleftup.sety (posleftup.y () + 2);
    ELSE if (key == 's')
      posleftup.sety (posleftup.y () - 2);
    Callbackfunc (Posleftup);
  }
  Void SetCallbackFunc (Void (* Fn) (Point Point)) {
    CallbackFunc = Fn;
  }
};
// Imitation Window
Class Mainwindow {
Private:
  STATIC VOID GetPosition (Point Point);
  Square Square;
Public:
  MainWindow () {
    POINT POS (10, 10);
    SQUARE = ​​Square (POS);
    Square.SetcallBackFunc (getposition);
    Square.move ('A');
    Square.move ('D');
    Square.move ('W');
    Square.move ('s');
  }
};
Void Mainwindow :: GetPosition (Point Point) {
    COUT & LT; & LT; point.x () & lt; & lt; ":" & lt; & lt; point.y () & lt; & lt; Endl;
}
INT MAIN () {
  Mainwindow Test;
  Return 0;
}

Answer 1, Authority 100%

Here are some points that I can speak.

In the class definition, I would first indicate Public , as this is a class interface.

class point {
Public:
  Point (int x, int y): xpos (x), ypos (y) {}
  Point (): Point (0,0) {}
  int x () {Return XPOS; }
  int y () {Return YPOS; }
  void setx (int x) {xpos = x; }
  Void SeTy (int y) {ypos = y; }
Private:
  INT XPOS;
  INT YPOS;
};

Do not combine the declarations in one line:

// bad:
  // INT XPOS, YPOS;
  // OK:
  INT XPOS;
  INT YPOS;

in setx and sety Do not use this :

void setx (int x) {xpos = x; }
Void SeTy (int y) {ypos = y; }

Use Switch in Move () . He fits very well here.

void move (Char Key) {
  Switch (Key)
  {
  Case 'A': Posleftup.Setx (Posleftup.x () - 2); Break;
  Case 'd': posleftup.setx (posleftup.x () + 2); Break;
  Case 'W': Posleftup.Sety (Posleftup.y () + 2); Break;
  Case 'S': Posleftup.Sety (Posleftup.y () - 2); Break;
  }
  Callbackfunc (Posleftup);
}

Use const variables where they should not change. The compiler will help you avoid stupid errors:

void move (const char key) {

in main () you can remove Return 0; . When main () reaches the end, and Return is missing, then return 0; will be implied automatically.


By “separating ads from the definitions in the class”, what I mentioned @Andrey, I mean the creation of individual files for the class declaration and to determine its methods. Take for example your Class Square :

Create two files: Square.hpp and Square.cpp .

Square.HPP :

# ifndef square_hpp
#Define Square_HPP.
#Include & lt; Functional & gt; 
#include "point.hpp" // File containing class Point
Class Square {
Public:
  Square ();
  Square (Const Point POS);
  Void Move (Const Char Key);
  void setcallbackfunc (STD :: FUNCTION & LT; Void (Const Point P) & GT;);
Private:
  STD :: FUNCTION & LT; Void (Const Point P) & GT; Callbackfunc;
  Point Posleftup;
};
#Endif // Square_HPP

In this file, we announced the Square class, that is, they listed its methods and members. This is enough to know how to use this class anywhere else elsewhere.

This design is called Header Guard (“Guardian Guard” – So this will be in Russian? )

# ifndef square_hpp
#Define Square_HPP.
// ...
#Endif // Square_HPP

It prevents the multiple attachment of this HPP file to the same CPP compilation file.

details of how these methods are implemented to place in the second file

Square.cpp :

# include "square.hpp"
Square :: Square (): Callbackfunc (NULLPTR)
{}
Square :: Square (Const Point POS):
  Callbackfunc (NullPTR),
  Posleftup (POS)
{}
Void Square :: Move (Const Char Key)
{
  Switch (Key)
  {
  Case 'A': Posleftup.Setx (Posleftup.x () - 2); Break;
  Case 'd': posleftup.setx (posleftup.x () + 2); Break;
  Case 'W': Posleftup.Sety (Posleftup.y () + 2); Break;
  Case 'S': Posleftup.Sety (Posleftup.y () - 2); Break;
  }
  If (Callbackfunc)
  {
    Callbackfunc (Posleftup);
  }
}
Void Square :: SetCallBackFunc (STD :: FUNCTION & LT; VOID (Const Point P) & GT; Fn)
{
  CallbackFunc = Fn;
}

So we separate the class interface from the implementation of its methods.


By the way, the class point could actually be just a structure, since its private members Xpos and YPOS are fully accessible for reading and Entries through the methods that you have identified. setx () and sety () do not perform any additional work, that is, there is no benefit here to hide x and Y as Private Members:

struct point {
  Point (): X (0), Y (0) {};
  POINT (Const int x, Const int y): x (x), y (y) {};
  int x;
  int y;
};

Another thing if we obliged setx () and sety () perform checking the transmitted values, then hide X and Y as private it would be justified:

void point :: setx (Const int Val)
{
  CONSTEXPR INT MIN_VALUE = -100;
  constExpr int max_value = 100;
  if (Val & lt; min_value || Val & gt; max_value)
  {
    // Error. The transmitted value is unacceptable.
    Throw Std :: Runtime_error ("setX (): value out of range");
  }
  x = Val;
}

CALBACK. Use the Tools from the & LT; Functional & GT; :

Std :: Function & LT; & GT; – Class shell, which can keep the function.

Std :: Bind () – a function that binds the execution of any function to another function, with the transmission of the arguments that can be predetermined.

# include & lt; functional & gt;
#Include & lt; iostream & gt;
Using Namespace STD;
Class Point {
Public:
  Point (int x, int y): xpos (x), ypos (y) {}
  Point (): Point (0,0) {}
  int x () {Return XPOS; }
  int y () {Return YPOS; }
  void setx (int x) {xpos = x; }
  Void SeTy (int y) {ypos = y; }
Private:
  INT XPOS;
  INT YPOS;
};
Class Square {
Public:
  Square () {}
  Square (POS): Posleftup (POS) {}
  // Imitation of the movement of the square on the window
  Void Move (Const Char Key) {
    Switch (Key)
    { 
Case 'A': Posleftup.Setx (Posleftup.x () - 2); Break;
    Case 'd': posleftup.setx (posleftup.x () + 2); Break;
    Case 'W': Posleftup.Sety (Posleftup.y () + 2); Break;
    Case 'S': Posleftup.Sety (Posleftup.y () - 2); Break;
    }
    If (Callbackfunc)
    {
      Callbackfunc (Posleftup);
    }
  }
  Void SetCallBackFunc (STD :: FUNCTION & LT; VOID (Const Point P) & GT; Fn) {
    CallbackFunc = Fn;
  }
Private:
  STD :: FUNCTION & LT; Void (Const Point P) & GT; callbackfunc = nullptr;
  Point Posleftup;
};
// Imitation Window
Class Mainwindow {
Private:
  STATIC VOID GetPosition (Point Point);
  Square Square;
Public:
  MainWindow () {
    Using Namespace Std :: Placeholders;
    POINT POS (10, 10);
    SQUARE = ​​Square (POS);
    Square.SetcallBackFunc (STD :: Bind (& amp; Mainwindow :: getposition, _1));
    Square.move ('A');
    Square.move ('D');
    Square.move ('W');
    Square.move ('s');
  }
};
Void Mainwindow :: GetPosition (Point Point) {
    COUT & LT; & LT; point.x () & lt; & lt; ":" & lt; & lt; point.y () & lt; & lt; Endl;
}
INT MAIN () {
  Mainwindow Test;
}

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions