使用类(2)

用类方法表示矢量

// class.h

#pragma once

#ifndef _CLASS_H_
#define _ClASS_H_

#include<iostream>

namespace VECTOR
{
	class Vector
	{
	public:
		enum Mode{RECT,POL};//两种表达矢量的方式
	private:
		double x;
		double y;
		double mag; //矢量的长度
		double ang; //矢量的方向,以角度表示
		Mode mode; //设置表达方式的模式
		void set_mag();
		void set_ang();
		void set_x();
		void set_y();
	public:
		Vector();
		Vector(double n1, double n2, Mode form = RECT); //默认模式为RECT
		void reset(double n1, double n2, Mode form = RECT);
		~Vector();
		//之所以要设置xval, yval, magval, angval这些函数,而不是将这些值存放在private区域中,就是为了在main函数中可以调用这些函数来获得这些值,若在private空间中则无法访问
		double xval() const  // xvalue
		{
			return x;
		}
		double yval() const  //yvalue;
		{
			return y;
		}
		double magval() const //magvalue
		{
			return mag;
		}
		double angval() const //angvalue
		{
			return ang;
		}
		void polar_mode();  //切换为polar mode
		void rect_mode();   //切换为rect mode

		// 重载运算符: 
		Vector operator+(const Vector& b)const;
		Vector operator-(const Vector& b)const;
		Vector operator-()const;
		Vector operator*(double n)const;

		// 友元函数:
		friend Vector operator*(double n, const Vector& a);
		friend std::ostream & operator<<(std::ostream& os,const Vector& v);
	};
}



#endif


// fuc.cpp

#include"class.h"
#include<cmath>  // 使用了 sqrt()求根号值函数,tan() 接受角度值返回斜率值, atan() 接受斜率值返回角度值, sin和cos接受角度值分别返回各自的正弦值和余弦值
using std::cout;
using std::sqrt;
using std::tan;
using std::atan;
using std::cos;
using std::sin;
using std::endl;

namespace VECTOR
{
	const double Rad_to_deg = 45 / atan(1.0);  // 电脑中一弧度所代表的角度 
	void Vector::set_mag()
	{
		mag = sqrt(x * x + y * y);
	}

	void Vector::set_ang()
	{
		if (x == 0 && y == 0)
		{
			ang = 0.0;
		}
		else
		{
			ang = atan2(y, x);  // atan2接受两个参数--x和y坐标,更加准确
		}
	}

	void Vector::set_x()
	{
		x = mag * cos(ang);
	}

	void Vector::set_y()
	{
		y = mag * sin(ang);
	}

	Vector::Vector()
	{
		x = y = mag = ang = 0.0;
		mode = RECT; // 默认模式为RECT;
	}

	Vector::Vector(double n1, double n2, Mode form)
	{
		mode = form;
		if (mode == RECT)
		{
			x = n1;
			y = n2;
			set_mag();
			set_ang();
		}
		else if (mode == POL)
		{
			mag = n1;
			ang = n2;
			set_x();
			set_y();
		}
		else
		{
			cout << "Incorrect 3rd argument to Vector() -- ";
			cout << "Vector set to 0" << endl;
			x = y = mag = ang = 0.0;
			mode = RECT;
		}
	}

	void Vector::reset(double n1, double n2, Mode form)
	{
		mode = form;
		if (mode == RECT)   // 根据x和y来设置距离和方向
		{
			x = n1;
			y = n2;
			set_mag();
			set_ang();
		}
		else if (mode == POL)  // 根据距离和方向来设置x和y
		{
			mag = n1;
			ang = n2;
			set_x();
			set_y();
		}
		else
		{
			cout << "Incorrect 3rd argument to Vector() -- ";
			cout << "Vector set to 0" << endl;
			x = y = mag = ang = 0.0;
			mode = RECT;
		}
	}

	Vector::~Vector()
	{
		//析构函数
	}

	void Vector::polar_mode()
	{
		mode = POL;
	}

	void Vector::rect_mode()
	{
		mode = RECT;
	}

	Vector Vector::operator+(const Vector& b)const
	{
		return Vector(x + b.x, y + b.y);  // 构造函数在运行时会自动创建一个临时的类对象来进行一系列的赋值,直接return一个构造函数的调用相当于return一个设置好值的类对象
	}

	Vector Vector::operator-(const Vector& b)const  //实现类对象值的相减
	{
		return Vector(x - b.x, y - b.y);
	}

	Vector Vector::operator-()const  //实现类对象的值变为相反数
	{
		return Vector(-x, -y);
	}

	Vector Vector::operator*(double n)const
	{
		return Vector(x * n, y * n);
	}

	//友元函数的定义(无需再加上friend,同时也无需再声明是类中的函数)
	Vector operator*(double n, const Vector& a)
	{
		return a * n;
	}

	std::ostream& operator<<(std::ostream& os, const Vector& v)  // 返回值为 ostream& 即 ostream流的一个引用
	{
		// 因为是友元函数,所以不在类作用域中,不可以直接使用属于类作用域的两个枚举量 RECT 和 POL   -- VECTOR::Vector::RECT/POL
		if (v.mode == Vector::RECT)
		{
			os << "(x,y) = (" << v.x << ", " << v.y << ")";
		}
		else if (v.mode == Vector::POL)
		{
			os << "(m,a)= (" << v.mag << ", "
				<< v.ang * Rad_to_deg << ")";
		}
		else
		{
			os << "Vector object mode is invalid";
		}
		return os;   // os重载 << 运算符的第一个参数,同时也是一个ostream流的引用
	}

}


// main.cpp

#include"class.h"
#include<cstdlib> // rand() ,srand(),
#include<ctime> //time()

int main()
{
	using namespace std;
	using VECTOR::Vector;
	srand(time(0)); //提供随机数种子
	double directions;
	Vector step;
	Vector result(0.0, 0.0);
	unsigned long steps = 0;
	double target;
	double dstep;
	cout << "Enter target distance (q to quit): ";
	while (cin >> target)  //输入数字 -- true   输入字母 -- false
	{
		cout << "Enter step length: ";
		if (!(cin >> dstep))  // 如果输入的不是数字,退出循环
		{
			break;
		}
		while (result.magval() < target)  //矢量的长度小于目标长度
		{
			directions = rand() % 360; //通过随机值来设置下次走的方向 
			step.reset(dstep, directions, Vector::POL);  //修改参数 -- 步子的长度,方向,以及表达方式
			result = result + step;  // 对象的重载相加
			steps++;  // 记录一共走了多少步
		}
		cout << "After " << steps << " steps,the subject has the following location: " << endl;
		cout << result << endl;  // 对象的cout显示在屏幕上 ( >>运算符的重载)
		result.polar_mode();
		cout << "or\n" << result << endl; // 重载 << 运算符的函数中的返回值为 ostream流的一个引用,所以可以连续使用<<运算符
		cout << "Average outward distance per step = " << result.magval() / steps << endl;
		steps = 0;
		result.reset(0.0, 0.0);
		cout << "Enter target distance(q to quit): ";
	}
	cout << "Bye~" << endl;

	//若输入过程中输入了很多字符,则用下面这几行代码来清除,清除完成后即cin,get()!='\n',再结束程序
	cin.clear();
	while (cin.get() != '\n')
	{
		continue;
	}

	system("pause");
	return 0;
}

知识点:

1.#include<cmath>  使用了 sqrt()求根号函数,tan() 接受角度值返回斜率值, atan() 接受斜率值返回角度值, atan2()接受x和y两个参数返回角度值,sin和cos接受角度值分别返回各自的正弦值和余弦值。

2.构造函数在运行时会自动创建一个临时的类对象来进行一系列的赋值,直接return一个构造函数的调用相当于return一个设置好值的类对象

3.实现真随机数:<cstdlib>中的srand()和rand()函数以及<ctime>中的time()函数

     srand(time(0))提供随机数种子后,rand()就可以提供随机数

4.之所以要设置xval,yval,magval,angval这些函数,而不是将这些值存放在private区域中,就是为了在main函数中可以调用这些函数来获得这些值,若在private空间中则无法访问

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值