C++小例子——01 向量类myVector

向量(vector)a=[x,y,z]\vec a=[x,y,z]a=[x,y,z]应用较广,比如节点的坐标x=[x,y,z]\vec x=[x,y,z]x=[x,y,z]、面的面积矢量Sf=[Sfx,Sfy,Sfz]\vec{S}_f=[Sf_x,Sf_y,Sf_z]Sf​=[Sfx​,Sfy​,Sfz​],面空间速度矢量u=[u,v,w]\vec u=[u,v,w]u=[u,v,w]等,都离不开它。同时,向量还有点乘、叉乘、求模(也称为幅值或二范数)的运算,以及向量与向量或标量的加减操作、向量与标量的乘除运算等。那么,咱们可以用C++定义一个向量类myVector,其包含三个成员变量x,y,zx,y,zx,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;
}

测试结果,表明所有函数均实现了其功能。
C++小例子——01 向量类myVector

上一篇:003 保存最后N个元素


下一篇:有趣的matlab编程