C++PrimerPlus第十一章类的使用:(矢量类)Vector类模拟醉鬼走路的问题

11.5再谈重载:一个矢量类

下面介绍另一种使用了运算符重载和友元的类设计–一个表示矢量的类。这个类还说明了类设计的其他方面,例如,在同一个对象中包含两种描述同一样东西的不同方式等。即使并不关心矢量,也可以在其他情况下使用这里介绍的很多新技术。矢量(vector),是工程和物理中使用的一个术语,它是一个有大小和方向的量。例如,推东西时,推的效果将取决于推力的大小和推的方向。从某个方向推可能会省力,而从相反的方向推则要费很大的劲。为完整地描述汽车的运动情况,应指出其运动速度(大小)和运动方向;如果逆行,则向高速公路的巡警辩解没有超速、超载是徒劳的(免疫学家和计算机专家使用术语矢量的方式不同,请不要考虑这一点,至少在第16章介绍计算机科学版本–vector 模板类之前应如此)。下面的旁注介绍了更多有关矢量的知识,但对于下面的C+示例来说,并不必完全理解这些知识。
## 矢量
假设工蜂发现了一个非凡的花蜜储藏处,它匆忙返回蜂巢,告知其他蜜蜂,该花蜜储藏处离蜂巢 120码。“这种信息是不完整的”,其他蜜蜂感到很茫然–“还必须告知方向!”,该工蜂答道:“太阳方向偏北30度”。知道了距离(大小)和方向,其他的蜜蜂能很快找到蜜源。蜜蜂得矢量。许多数量都有大小和方向。例如,推的效果取决于力气的大小和方向。在计算机屏幕上移动对象时也涉及到距离和方向。可以使用矢量来描述这类问题。例如,可以用失量来描述如何在屏幕上移动(放置)对象,即用箭头从起始位置画到终止位置,来对它作形象化处理。失量的长度是其大小–描述了移动的距离;箭头的指向描述了方向( 参见图 11.1)。表示这种位置变化的矢量称为位移矢量( displacementvector ).
现在,假设您是[hanappa–伟大的毛象猎手。猎狗报告毛象群位于西北 14.1公里处。但由于当时刮的是东南风,您不想从东南方向接近毛象群,因此先向西走了 10公里,再向北走了 10 公里,最终从南面接近毛象群。您知道这两个位移矢量与指向西北的 14.1公里的矢量的方向相同。伟大的毛象猎手 Lhanappa也知道如何将两个矢量相加。

将两个矢量相加有一种简单的几何解释。首先,画一个矢量,然后从第一个矢量的尾部开始画第二个矢量。最后从第一个失量的开始处向第二个矢量的结尾处画一个矢量。第三个矢量表示前两个矢量的和(参见图 11.2)。注意,两个失量之和的长度可能小于它们的长度之和。
显然,应为矢量重载运算符。首先,无法用一个数来表示矢量,因此应创建一个类来表示矢量。其次,矢量与普通数学运算(如加法、减法)有相似之处。这种相似表明,应重载运算符,使之能用于矢量。出于简化的目的,本节将实现一个二维矢量(如屏幕位移),而不是三维矢量(如表示直升机或体操运动员的运动情况)。描述二维矢量只需两个数,但可以选择到底使用哪两个数:
可以用大小(长度)和方向(角度)描述矢量:
可以用分量x和y表示矢量。
两个分量分别是水平矢量(x分量)和垂直天量(y分量),将其相加可以得到最终的矢量。例如,可以这样描述点的运动:向右移动30个单位,再向上移动40个单位(参见图11.3)。这将把该点沿与水平方向呈 53.1度的方向移动50个单位,因此,水平分量为30个单位、垂直分量为40个单位的矢量,与长度为50个单位、方向为53.1度的矢量相同。位移矢量指的是从何处开始、到何处结束,而不是经过的路线。这种表示基本上和第7章在直角坐标与极坐标之间转换的程序中介绍的相同。

程序清单11.15是一个小程序,它使用了修订后的Vector类。该程序模拟了著名的醉鬼走路问题(Drunkard Walk problem)。实际上,醉鬼被认为是一个有许多健康问题的人,而不是大家娱乐消遣的谈资,因此这个问题通常被称为随机漫步问题。其意思是,将一个人领到街灯柱下。这个人开始走动,但每一步的方向都是随机的(与前一步不同)。这个问题的一种表述是,这个人走到离灯柱50英尺处需要多少步。从矢量的角度看,这相当于不断将方向随机的天量相加,直到长度超过50英尺。程序清单 11.15允许用户选择行走距离和步长。该程序用一个变量来表示位置(一个矢量),并报告到达指定距离处(用两种格式表示)所需的步数。可以看到,行走者前进得相当慢。虽然走了1000步,每步的距离为2英尺,但离起点可能只有50英尺。这个程序将行走者所走的净距离(这里为50英尺)除以步数,来指出这种行走方式的低效性。随机改变方向使得该平均值远远小于步长。为了随机选择方向,该程序使用了标准库函数rand()、srand()和time()(参见程序说明)。请务必将程序清单11.14和程序清单 11.15一起进行编译。

//vect.h -- Vector class with <<,mode state
#ifndef	VECTOR_H_	
#define VECTOR_H_

#include<iostream>
namespace VECTOR
{
   
	class Vector
	{
   
	public:
		enum Mode{
   RECT,POL};
		//RECT for rectangular,POL for Polar modes
	private:
		double x;//horizontal value
		double y;//vertical value
		double mag; //length of value
		double ang;//direction of vector in degrees
		Mode mode;//RECT or POL
		//private methods for setting values
		void set_mag();
		void set_ang();
		void set_x();
		void set_y();
	public:
		Vector();
		Vector(double n1, double n2, Mode form = RECT);
		void reset(double n1, double n2, Mode form = RECT);
		~Vector();
		double xval()const {
    return x; }//report x val
		double yval()const {
    return y; }//report y val
		double magVal()const {
    return mag; }//report magnitude
		double angval()const {
    return ang; }//report angle
		void polar_mode();//set mode to POL
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值