向量(vector)a=[x,y,z]应用较广,比如节点的坐标x=[x,y,z]、面的面积矢量Sf=[Sfx,Sfy,Sfz],面空间速度矢量u=[u,v,w]等,都离不开它。同时,向量还有点乘、叉乘、求模(也称为幅值或二范数)的运算,以及向量与向量或标量的加减操作、向量与标量的乘除运算等。那么,咱们可以用C++定义一个向量类myVector,其包含三个成员变量x,y,z,可通过三个分量来构造,也可通过另一个myVector对象来构造,重载操作符+、-、*、/来完成相关运算,重载赋值符=,重载输出流<<来实现输出,定义友元函数dotProduct、crossProduct、norm来计算点乘、叉乘、求模……写好的程序如下:
注意:这里的myVector和C++里自带的库文件vector不同,这里只是含3个分量的空间矢量,而C++中的vector则更类似于一维变长度数组。
myVector.h头文件
// 2020-06-09
// class myVector - head file
// Author: Guanhua Mei
// definition and functions of a myVector [x, y, z]
// can be used for points, velocity, etc. in CFD
#include <iostream>
class myVector
{
private:
double m_dX;
double m_dY;
double m_dZ;
public:
// construct with input x, y and z, default 0
myVector(double x = 0.0, double y = 0.0, double z = 0.0);
// construct with another myVector
myVector(const myVector &);
// destructor, do nothing
~myVector();
// print
void print() const;
// get x, y, z
double getX() const;
double getY() const;
double getZ() const;
// set x, y, z
void setX(double x = 0.0);
void setY(double y = 0.0);
void setZ(double z = 0.0);
// set total value
void setVal(double x = 0.0, double y = 0.0, double z = 0.0);
// overload =
myVector & operator=(const myVector &);
// overload operators
// +: (x1, y1, z1) + (x2, y2, z2) = (x1 + x2, y1 + y2, z1 + z2)
friend myVector operator+(const myVector &, const myVector &);
// +: (x1, y1, z1) + b = (x1 + b, y1 + b, z1 + b)
friend myVector operator+(const myVector &, double);
// -: (x1, y1, z1) - (x2, y2, z2) = (x1 - x2, y1 - y2, z1 - z2)
friend myVector operator-(const myVector &, const myVector &);
// -: (x1, y1, z1) - b = (x1 - b, y1 - b, z1 - b)
friend myVector operator-(const myVector &, double);
// +=
myVector & operator+=(const myVector &);
myVector & operator+=(double);
// -=
myVector & operator-=(const myVector &);
myVector & operator-=(double);
// multiply
// *: (x1, y1, z1) * b = (x1 * b, y1 * b, z1 * b)
friend myVector operator*(const myVector &, double);
// *: b * (x1, y1, z1) = (x1, y1, z1) * b
friend myVector operator*(double, const myVector &);
// divide
// /: (x1, y1, z1) / b = (x1 / b, y1 / b, z1 / b)
friend myVector operator/(const myVector &, double);
// dot product
// (x1, y1, z1) dot (x2, y2, z2) = x1 * x2 + y1 * y2 + z1 * z2
friend double dotProduct(const myVector &, const myVector &);
// cross product
// (x1, y1, z1) cross (x2, y2, z2) =
// | i j k |
// | x1 y1 z1 |
// | x2 y2 z2 |
friend myVector crossProduct(const myVector &, const myVector &);
// output <<
friend std::ostream & operator<<(std::ostream & os, const myVector &);
// magnitude
// norm([x, y, z]) = sqrt(x^2 + y^2 + z^2)
friend double norm(const myVector &);
};
myVector.cpp文件
// 2020-06-09
// class myVector - cpp file
// Author: Guanhua Mei
#include "myVector.h"
// construct with input x, y and z, default 0
myVector::myVector(double x, double y, double z)
{
m_dX = x;
m_dY = y;
m_dZ = z;
}
// construct with another myVector
myVector::myVector(const myVector & vct)
{
m_dX = vct.m_dX;
m_dY = vct.m_dY;
m_dZ = vct.m_dZ;
}
// destructor, do nothing
myVector::~myVector()
{
}
// print
void myVector::print() const
{
std::cout <<
"(" << m_dX << ", " << m_dY << ", " << m_dZ << ")"
<< std::endl;
}
// get x, y, z
double myVector::getX() const
{
return m_dX;
}
double myVector::getY() const
{
return m_dY;
}
double myVector::getZ() const
{
return m_dZ;
}
// set x, y, z
void myVector::setX(double x)
{
m_dX = x;
}
void myVector::setY(double y)
{
m_dY = y;
}
void myVector::setZ(double z)
{
m_dZ = z;
}
void myVector::setVal(double x, double y, double z)
{
m_dX = x;
m_dY = y;
m_dZ = z;
}
// overload =
myVector & myVector::operator=(const myVector & vct)
{
m_dX = vct.m_dX;
m_dY = vct.m_dY;
m_dZ = vct.m_dZ;
return *this;
}
// +: (x1, y1, z1) + (x2, y2, z2) = (x1 + x2, y1 + y2, z1 + z2)
myVector operator+(const myVector & vct1, const myVector & vct2)
{
myVector tmp(vct1.m_dX + vct2.m_dX,
vct1.m_dY + vct2.m_dY, vct1.m_dZ + vct2.m_dZ);
return tmp;
}
// +: (x1, y1, z1) + b = (x1 + b, y1 + b, z1 + b)
myVector operator+(const myVector & vct1, double dbl)
{
myVector tmp(vct1.m_dX + dbl,
vct1.m_dY + dbl, vct1.m_dZ + dbl);
return tmp;
}
// -: (x1, y1, z1) - (x2, y2, z2) = (x1 - x2, y1 - y2, z1 - z2)
myVector operator-(const myVector & vct1, const myVector & vct2)
{
myVector tmp(vct1.m_dX - vct2.m_dX,
vct1.m_dY - vct2.m_dY, vct1.m_dZ - vct2.m_dZ);
return tmp;
}
// -: (x1, y1, z1) - b = (x1 - b, y1 - b, z1 - b)
myVector operator-(const myVector & vct1, double dbl)
{
myVector tmp(vct1.m_dX - dbl,
vct1.m_dY - dbl, vct1.m_dZ - dbl);
return tmp;
}
// +=
myVector & myVector::operator+=(const myVector & vct)
{
m_dX += vct.m_dX;
m_dY += vct.m_dY;
m_dZ += vct.m_dZ;
return *this;
}
myVector & myVector::operator+=(double dbl)
{
m_dX += dbl;
m_dY += dbl;
m_dZ += dbl;
return *this;
}
// -=
myVector & myVector::operator-=(const myVector & vct)
{
m_dX -= vct.m_dX;
m_dY -= vct.m_dY;
m_dZ -= vct.m_dZ;
return *this;
}
myVector & myVector::operator-=(double dbl)
{
m_dX -= dbl;
m_dY -= dbl;
m_dZ -= dbl;
return *this;
}
// multiply
// *: (x1, y1, z1) * b = (x1 * b, y1 * b, z1 * b)
myVector operator*(const myVector & vct, double dbl)
{
myVector tmp(vct.m_dX * dbl, vct.m_dY * dbl, vct.m_dZ * dbl);
return tmp;
}
// *: b * (x1, y1, z1) = (x1, y1, z1) * b
myVector operator*(double dbl, const myVector & vct)
{
return (vct * dbl);
}
// divide
// /: (x1, y1, z1) / b = (x1 / b, y1 / b, z1 / b)
myVector operator/(const myVector & vct, double dbl)
{
// if dbl equals 0, it will return INF
return (vct * (1.0 / dbl));
}
// dot product
// (x1, y1, z1) dot (x2, y2, z2) = x1 * x2 + y1 * y2 + z1 * z2
double dotProduct(const myVector & vct1, const myVector & vct2)
{
return (vct1.m_dX * vct2.m_dX + vct1.m_dY * vct2.m_dY
+ vct1.m_dZ * vct2.m_dZ);
}
// cross product
// (x1, y1, z1) cross (x2, y2, z2) =
// | i j k |
// | x1 y1 z1 |
// | x2 y2 z2 |
myVector crossProduct
(const myVector & vct1, const myVector & vct2)
{
myVector tmp;
tmp.m_dX = vct1.m_dY * vct2.m_dZ - vct1.m_dZ * vct2.m_dY;
tmp.m_dY = vct1.m_dZ * vct2.m_dX - vct1.m_dX * vct2.m_dZ;
tmp.m_dZ = vct1.m_dX * vct2.m_dY - vct1.m_dY * vct2.m_dX;
return tmp;
}
// output stream <<
std::ostream & operator<<(std::ostream & os, const myVector & vct)
{
os << "(" << vct.m_dX << ", " << vct.m_dY << ", " << vct.m_dZ << ")";
return os;
}
// magnitude
// norm([x, y, z]) = sqrt(x^2 + y^2 + z^2)
double norm(const myVector & vct)
{
double tmp;
tmp = std::sqrt(vct.m_dX * vct.m_dX
+ vct.m_dY * vct.m_dY + vct.m_dZ * vct.m_dZ);
return tmp;
}
测试主函数main.cpp
// 2020-06-09
// test class myVector
// Author: Guanhua Mei
#include <iostream>
#include "myVector.h"
using namespace std;
int main()
{
// test constructor
myVector a;
myVector b(1.2);
myVector c(2.3, 3.4, 5.6);
myVector d(5.6, 6.7, 7.8);
// test print()
cout << "a:"; a.print();
// test <<
cout << "b:" << b << endl;
cout << "c:" << c << endl;
cout << "d:" << d << endl;
myVector e;
// test =
e = d;
cout << "After e = d, e =:" << e << endl;
// test setVal
e.setVal(1, 2, 3);
cout << "After e.setVal(1,2,3), e: " << e << endl;
// test +
cout << "d + c:" << d + c << endl;
cout << "d + 1:" << d + 1 << endl;
// test -
cout << "d - c:" << d - c << endl;
cout << "d - 1:" << d - 1 << endl;
// test *
cout << "d * 2.0:" << d * 2.0 << endl;
cout << "2.0 * d:" << 2.0 * d << endl;
// test /
cout << "d / 2.0:" << d / 2.0 << endl;
cout << "d / 0.0:" << d / 0.0 << endl;
// test dotProduct
cout << "dotProduct(d, c):" << dotProduct(d, c) << endl;
// test crossProduct
cout << "crossProduct(d, c):" << crossProduct(d,c) << endl;
// test norm 2
cout << "norm(d):" << norm(d) << endl;
// test +=
d += c;
cout << "After d += c, d = :" << d << endl;
// test -=
d -= c;
cout << "After d -= c, d = :" << d << endl;
return 0;
}
测试结果,表明所有函数均实现了其功能。