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;
}