问题描述
描述一个二维矢量类只需要两个数,可以是以下两种经典的描述方法:
- 可以用大小(长度)和方向(角度)表示矢量,即使用极坐标系来描述。 可以用分量x和y来
- 表示矢量,即使用直角坐标系来描述。
两者各有优点,有时一种方便,有时另一种更方便,所以我们设计一个矢量类,类描述中包含这两种表示形式。此外,所描述的类成员函数相对较多,所以采用分文件编写的形式来写,逻辑上会清晰很多~
头文件 vector.h
可能由于和模板类vector名称撞车,这里我们使用namespace VECTOR,头文件中包含了类成员和方法的声明~
#pragma once
#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);
void reset(double n1, double n2, Mode form = RECT);
~Vector();
double xval() const { return x; }
double yval() const { return y; }
double magval() const { return mag; }
double angval() const { return ang; }
void polar_mode();
void rect_mode();
Vector operator+(const Vector& v) const;
Vector operator-(const Vector& v) const;
Vector operator-() const;
Vector operator*(double n) const;
friend std::ostream& operator<<(std::ostream& cout, const Vector& v);
};
}
源文件 vector.cpp
这里介绍了头文件中声明的成员方法的具体实现~
#include <cmath>
#include "vector.h"
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;
namespace VECTOR
{
const double Rad_to_deg = 45.0 / atan(1.0);
// private 成员函数
void Vector::set_mag()
{
mag = sqrt(x * x + y * y);
}
void Vector::set_ang()
{
if (x == 0 && y == 0)
{
ang = 0;
}
else
{
ang = atan2(y, x);
}
}
void Vector::set_x()
{
x = mag * cos(ang);
}
void Vector::set_y()
{
y = mag * sin(ang);
}
// public 成员函数
Vector::Vector()
{
x = y = mag = ang = 0;
mode = RECT;
}
Vector::Vector(double n1, double n2, Mode form)
{
mode = form;
if (mode == RECT)
{
x = n1;
y = n2;
set_mag();
set_ang();
}
else
{
mag = n1;
ang = n2;
set_x();
set_y();
}
}
void Vector::reset(double n1, double n2, Mode form)
{
mode = form;
if (mode == RECT)
{
x = n1;
y = n2;
set_mag();
set_ang();
}
else
{
mag = n1;
ang = n2;
set_x();
set_y();
}
}
Vector::~Vector()
{
// 析构函数 空实现
}
void Vector::polar_mode()
{
mode = POL;
}
void Vector::rect_mode()
{
mode = RECT;
}
Vector Vector::operator+(const Vector& v) const
{
return Vector(this->x + v.x, this->y + v.y);
}
Vector Vector::operator-(const Vector& v) const
{
return Vector(this->x - v.x, this->y - v.y);
}
Vector Vector::operator-() const
{
return Vector(-this->x, -this->y);
}
Vector Vector::operator*(double n) const
{
return Vector(this->x * n, this->y * n);
}
std::ostream& operator<<(std::ostream& cout, const Vector& v)
{
if (v.mode == Vector::RECT)
{
cout << "(x, y) = (" << v.x << ", " << v.y << ")" << std::endl;
}
else if(v.mode == Vector::POL)
{
cout << "(mag, ang) = (" << v.mag << "," << v.ang * Rad_to_deg << ")" << std::endl;
}
else
{
cout << "Vector object mode is invalid" << std::endl;
}
return cout;
}
}
在main.cpp中进行测试
最后进行一些简单的测试,只挑了其中两三个功能~
#include <iostream>
#include "vector.h"
using namespace VECTOR;
using namespace std;
void test01()
{
Vector v;
v.reset(3, 4);
cout << v << endl;
v.polar_mode();
cout << v << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
结果显示如下:
证明我们所设计的矢量类可以正常运行哦~