我想确保我正确和充分地编写了所有内容。请告诉我代码中存在哪些错误,最好是关于如何正确处理的建议。
#include <iostream>
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->xPos = x; }
void setY(int y) { this->yPos = y; }
};
class Square {
private:
void(*callBackFunc)(Point point);
Point posLeftUp;
public:
Square(){}
Square(Point pos) : posLeftUp(pos) {}
//Имитация движения квадрата по окну
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;
}
};
//Имитация окна
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 << point.x() << " : " << point.y() << endl;
}
int main() {
MainWindow test;
return 0;
}
以下是我可以评论的几点。
在类定义中,我将首先指定
public
,因为这是类的接口。不要在一行上合并声明:
在
setX
并且setY
不使用this
:switch
中使用Move()
。他非常适合这里。const
在不应该改变的地方使用变量。编译器将帮助您避免愚蠢的错误:在
main()
可以删除return 0;
。当它main()
到达结尾并且return
丢失时,它将return 0;
自动被暗示。正如@Andrey 所提到的,通过“将声明与类中的定义分开”,这意味着创建单独的文件来声明类和定义其方法。以你的为例
class Square
:让我们创建两个文件:
square.hpp
和square.cpp
.square.hpp
:在这个文件中,我们声明了类
Square
,即我们列出了它的方法和成员。这足以知道如何在其他地方使用这个类。这种设计被称为 Header guard(“header guard” -所以它会是俄语?)
它可以防止该文件在编译期间多次
hpp
嵌套在同一个文件中。cpp
这些方法如何实现的细节将放在第二个文件中
square.cpp
:因此,我们将类接口与其方法的实现分开。
顺便说一句,一个类
Point
实际上可能只是一个结构,因为它的私有成员通过您定义的方法xPos
是yPos
完全可读和可写的。setX()
并且setY()
不做额外的工作,即隐藏为私人成员x
也没有任何好处:y
如果我们有义务检查传递的值,那是另一回事
setX()
,然后将其setY()
隐藏为私有是合理的:x
y
关于回调。使用标题中的工具
<functional>
:std::function<>
- 可以包含函数的包装类。std::bind()
- 将一个函数的执行绑定到另一个函数的函数,向它传递可以预定义的参数。