1.类之间的相互使用
当一个类中要使用另一个类的对象的引用,但是被使用类被定义在该类后面时,就必须进行类的前向声明。但是当在该类中还要使用到后面类的成员函数时,就算进行了前向声明也会报错,这时就需要将类中的成员函数定义和声明进行分开,且两个类的成员函数都要写在所有类的后面。
2.类继承和构造的写法
类继承的写法,如果一个类继承与另一个类要在类名后面加上冒号 并写上要继承父类的权限性质 如public,private,protected,然后加上要继承的父类的类名。
继承类之间的构造函数写法,子类在进行构造时可以在初始化列表中使用父类的构造函数并进行传参来初始化父类的成员变量 。若子类没有在构造函数的初始化列表中使用父类的构造函数,则在子类构造时会自动匹配父类的默认构造函数或者全缺省构造函数,如果没有匹配到相应的构造函数则会报错。在子类中要想直接使用父类的成员变量而又不想让类外部使用则可以将成员变量设为protected权限。在子类构造的初始化列表中使用父类构造如下:
cpp
Hero(int health = 0, int blue = 0, int damage = 0)
:Basic(health, damage)
, _blue(blue)
, _reserveBlue(0)
{
}
3.使用虚函数来实现多态
在面向对象语言中多态是的三大特性之一,c++中可以通过当子类继承父类时父类使用虚函数子类重写父类的虚函数来实现多态。c++中多态的表现有静态多态:函数重载,运算符重载,模板,动态多态:虚函数,虚析构函数 。在虚析构中比较常见的体现方式就是使用父类指针来指向子类对象 ,在父类指针delete时父类使用虚析构后会调用到子类的析构,对子类对象所占用的空间进行析构,但是如果没有使用虚析构时则不会调用到子类析构造成内存泄露。
4.五子棋游戏
五子棋游戏的图形实现是通过的EasyX图形库。首先是对于棋盘的设计,棋盘通过一个棋盘类来实现成员变量有棋盘偏移量,棋盘大小,棋盘格子大小 ,整个棋盘的绘制也可以通过这三个量进行。棋盘的偏移量来决定棋盘坐标原点相对于窗口坐标原点的偏移,棋盘的大小来决定了这个棋盘的长和宽从棋盘原点的延伸 ,棋盘格子的大小用来进行其中棋盘线的绘制的偏移。然后在该棋盘类的构造函数中进行棋盘的绘制。
对于五子棋的棋子坐标设计,就是要通过由实际鼠标的坐标来映射到虚拟的坐标点再通过虚拟的坐标点对应的实际坐标的方式来设置实际鼠标点击后棋子的落点坐标。棋子这坐标之间的转化也依赖于偏移量和棋盘格子大小。具体三坐标间的转化可以看如下程序:
cpp
//转化为虚拟坐标
pie._x = (m.x - _gridOffset) / _gridSize;
pie._y = (m.y - _gridOffset) / _gridSize;
//将虚拟坐标转化为棋盘对应坐标
int x = pie._x * _gridSize + _gridOffset;
int y = pie._y * _gridSize + _gridOffset;
游戏胜利的判断。游戏胜利主要有四种情况:横着连成5个,竖着连成5个,斜向下连成5个,斜向上连成5个 ,首先定义三个set容器,用来分别进行三种对战颜色的棋子坐标的存储,因为set容器可以进行排序所以选择set容器来对坐标进行存储 ,但是要注意的是因为要存储的是一个坐标值为自定义类型所以要再该棋子类中实现运算符的重载 来供set容器使用。然后对于胜利的四种情况的判断,因为要涉及到棋子前后间的逻辑关系所以可以使用到vector容器,通过遍历set容器将其中的元素放入到vector容器中,因为vector容器可以进行下标访问适合随时访问前后关系。四钟胜利情况的具体逻辑程序如下:
cpp
for (int i = 0; i < vec.size() - 1; i++)
{
if (vec[i + 1]._x - vec[i]._x == 1 && vec[i + 1]._y == vec[i]._y)
{
if (++count1 == 5)
{
//有棋子横向成五,该棋子胜利
//cout << "有棋子横向成五,该棋子胜利" << endl;
if (pie.color == 1)
cout << "黑棋胜利" << endl;
else if (pie.color == 2)
cout << "白棋胜利" << endl;
else
cout << "蓝棋胜利" << endl;
exit(0);
}
//cout << "count1:" << count1 << endl;
}
else if (vec[i + 1]._x - vec[i]._x == 1 && vec[i + 1]._y - vec[i]._y == 1)
{
if (++count2 == 5)
{
//有棋子斜向上成五该棋子胜利
//cout << "有棋子斜向下成五,该棋子胜利" << endl;
if (pie.color == 1)
cout << "黑棋胜利" << endl;
else if (pie.color == 2)
cout << "白棋胜利" << endl;
else
cout << "蓝棋胜利" << endl;
exit(0);
}
}
else if (vec[i + 1]._x - vec[i]._x == 1 && vec[i + 1]._y - vec[i]._y == -1)
{
if (++count3 == 5)
{
//有棋子斜向下成五该棋子胜利
//cout << "有棋子斜向上成五,该棋子胜利" << endl;
if (pie.color == 1)
cout << "黑棋胜利" << endl;
else if (pie.color == 2)
cout << "白棋胜利" << endl;
else
cout << "蓝棋胜利" << endl;
exit(0);
}
}
else if (vec[i + 1]._x - vec[i]._x == 0 && vec[i + 1]._y - vec[i]._y == 1)
{
if (++count4 == 5)
{
//有棋子竖着成五该棋子胜利
//cout << "有棋子竖着成五,该棋子胜利" << endl;
if (pie.color == 1)
cout << "黑棋胜利" << endl;
else if (pie.color == 2)
cout << "白棋胜利" << endl;
else
cout << "蓝棋胜利" << endl;
exit(0);
}
}
else
{
count1 = 1;
count2 = 1;
count3 = 1;
count4 = 1;
}
}
5.整数相除混合小数
我们要得到一个比较精确的小数结果时,其中又混合着整数相除这时就要注意了,当整数相除的运算符优先级高或者整数相除优先运算时因为此时的整数都还没有和小数进行运算没有类型提升,所以该整数相除后的结果依旧会得到一个整数去掉小数部分,所以就造成了想要得到小数的结果不准确 ,可以通过先将整数与小数进行运算类型提升后再计算相除,这样子结果就会准确了。
6.括号的使用
括号的优先级相比于其他运算符的优先级是要高的,所以在进行多项加减乘除运算时要注意使用括号来保证运算结果的准确性。
7.最长问题
最长问题,常见的问题逻辑就是要你计算一段数据中连续的最长的什么性质,因为要求的连续所以当每次断连了之后就要重新进行计算,但是这时需要知道将以前的连续的数量进行保存通过比较来将最长的结果保存记录下来。