C++ 简单Vector模板类

本文介绍了初学者如何创建一个简单的C++ Vector模板类,使用template关键字实现n维向量的功能。在编写过程中,作者强调了几个关键点:模板类的函数定义需与头文件在同一cpp文件内;成员函数(包括友元函数)需指定模板参数;友元函数通常声明为非约束模板。文章提及目前的不足是缺少对模板深入理解和异常处理机制。

刚接触类的相关内容,完成了简单的Vector模板类的项目。

用template <class T>来实现n维向量的相关性质。

写的时候其中有几个关键的地方

1.模板类的函数定义必须和头文件放在一个cpp文件里,系统不支持模板类的单独编译。

2.定义模板类的成员(友元)函数时,都要加 template <class T>  or template <typename T>。

3.对于模板类的友元函数,都声明成了非约束(unbound)模板友元。  ( 详见参考blog)

4.缺陷在于没有更细致的了解模板以及没有添加异常处理等情况。


以下简单代码实现

//vector.h

#ifndef vector_h
#define vector_h
#include <algorithm>
#include <cstring>
#include <math.h>
#include "vector.h"
#include<iostream>
using namespace std;

template<class T>
class vector
{
	public:
       vector();
	   vector(vector<T> &temp);
	   ~vector(){if(array !=NULL) delete array;}	
	   vector & operator=(const vector<T>& temp);
		
       template <typename TYPE> friend vector<TYPE> operator+(vector<TYPE> &temp1,vector<TYPE> &temp2);
       template <typename TYPE> friend vector<TYPE> operator-(vector<TYPE> &temp1,vector<TYPE> &temp2);
	   
	   T Find(T& temp);
	   T operator*(vector<T> &temp);
	   T norm (vector<T> &temp);
	   
	   
       vector & unit(vector<T> &temp);
	   
	   
       template <typename TYPE> friend vector<TYPE> Vector_Cross_Product(vector<TYPE> &temp1,vector<TYPE> &temp2);
	   template <typename TYPE> friend bool Perpendicular(vector<TYPE> &temp1,vector<TYPE> &temp2);
	   template <typename TYPE> friend bool Parallel(vector<TYPE> &temp1,vector<TYPE> &temp2);
	   template <typename TYPE> friend ostream & operator<<(ostream &out, const vector<TYPE> &temp);
	   template <typename TYPE> friend istream & operator>>(istream &in,vector<TYPE> &temp);
	   
	protected:
		T *array;
		int len;
		int sum;
};

//0.默认构造函数
template <class T>
vector<T>::vector()
{
   if(len==0)
	   array=NULL;
}


//1.拷贝构造函数 
template <class T>
vector<T> :: vector<T>(vector<T> &temp){
	len=temp.len;
	array= new T[len];
	for(int i=0;i<=len;i++)
	   array[i]=temp.array[i];
}

//2.向量的赋值
template<class T>
vector<T> & vector<T> :: operator=(const vector<T> &temp){
	len=temp.len;
	array=new T[len];
	for(int i=0;i<=len;i++)
	{
		array[i]=temp.array[i];
	};
	return *this;
}

//3.在向量中查找某个分向量的位置
template<class T>
T vector<T>:: Find(T& temp){
 	 for(int i=0;i<=len;i++)
		if(array[i]==temp)
			return i;
	 return -1;
}

//4.向量的加法
template<class T>
vector<T> operator+(vector<T> &temp1,vector<T> &temp2){
	vector<T> temp;
	temp.len=temp1.len;
	temp.array=new T[temp.len];
	for(int i=0;i<=temp1.len;i++)
		temp.array[i]=temp1.array[i]+temp2.array[i];
	return temp;
}

//5.向量的减法
template<class T>
vector<T> operator-(vector<T> &temp1,vector<T> &temp2){
	vector<T> temp;
	temp.len=temp1.len;
	temp.array=new T[temp.len];
	for(int i=0;i<temp1.len;i++)
		temp.array[i]=temp1.array[i]-temp2.array[i];
	return temp;
}

//6.向量的点积
template <class T>
T vector<T> :: operator * (vector<T> &temp){
    len=temp.len;
    sum=0;
	for(int i=0;i<len;i++){;
	    sum+= array[i]*temp.array[i];
	}
    return sum;
}


//7.向量的模
template <class T>
T vector<T> :: norm(vector<T> &temp){
	 len=temp.len;
	 sum=0;
	 for(int i=0;i<len;i++)
	    sum+= temp.array[i]*temp.array[i];
	 return sqrt((double)sum);
} 

//8.向量的单位化
template<class T>
vector<T> & vector<T> :: unit(vector<T> &temp1){
	 vector<T> temp;
 	 temp.len=temp1.len;
	 temp.array=new T[temp1.len];
	 T total=temp1.norm(temp1);	 
 	 for(int i=0;i<temp.len;i++){
	    temp.array[i]=temp1.array[i]/total;
        cout<<temp.array[i]<<' ';
	 }
	 //(temp1.norm(temp1)); 
 	 return temp;
}


//9.向量的叉积(三维)
template<class T>
vector<T> Vector_Cross_Product(vector<T> &temp1,vector<T> &temp2){
	 vector<T> temp;
	 temp.len=temp1.len;
	 temp.array=new T[temp.len];
     if(temp.len==3)
     {
    	temp.array[0]=temp1.array[1]*temp2.array[2]-temp1.array[2]*temp2.array[1];
     	temp.array[1]=temp1.array[2]*temp2.array[0]-temp1.array[0]*temp2.array[2];
     	temp.array[2]=temp1.array[0]*temp2.array[1]-temp1.array[1]*temp2.array[0];
	 }
	 return temp; 
}


//10.判断向量垂直
template<class T>
bool Perpendicular(vector<T> &temp1,vector<T> &temp2){
	  int ans=0;
	  for(int i=0;i<temp1.len;i++)
	     ans+=temp1.array[i]*temp2.array[i];
	  return ans==0;
}

//11.判断向量平行 
template<class T>
bool Parallel(vector<T> &temp1,vector<T> &temp2){
      int flag=1;
	  for(int j=0;j<temp1.len;j++)
	  {
		if(!temp1.array[j] && !temp1.array[j])
			if(j==temp1.len-1)break;
		    else continue;
	  	else if(temp1.array[j] && temp1.array[j])
	  	{
	  		int ans=temp1.array[j]/temp2.array[j];
            for(int i=j;i<temp1.len;i++)
	        {
	        	if((temp1.array[i] && !temp2.array[i]) || (!temp1.array[i] && temp2.array[i]) ){
	        		flag=0;break;
				}
	            else if(temp1.array[i]/temp2.array[i]!=ans){
	      	       flag=0;break;
		        }	
	        }        
		}
	  } 
	  
	  if(flag) return 1;
	  else return 0;
}

template<class T>
ostream & operator<<(ostream &out, const vector<T> &temp){
	for(int i=0;i<temp.len;i++){
		out<<temp.array[i]<<' ';
	}
	return out;
}

template<class T>
istream & operator>>(istream &in,vector<T> &temp){
    cout<<"请输入维数:"<<endl;
    cin>>temp.len;
    cout<<"Please input the array: "<<endl; 
    temp.array = new T[temp.len];
    for(int i=0;i<temp.len;i++)
      in>>temp.array[i];
	return in;
}

#endif



//test_vector.cpp

#include <iomanip>
#include <iostream>
#include <cstring>
#include <math.h>
#include <conio.h>
#include "vector.h"
const int maxn=1e5+5;
using namespace std;

/*
测试:
0.构造函数,拷贝构造函数
1. I/O操作 
2.向量的赋值
3.查找向量分量位置 
4.向量的加法
5.向量的减法
6.向量的点积
7.向量的模
8.向量的单位化
9.向量的叉积
10.判断向量垂直
11.判断向量平行 
*/

void test1(){
	cout<<"Please input integer vector"<<endl;
	vector<int >v;
	cin>>v;
	cout<<v<<endl;
	cout<<"Please input double vector"<<endl;
	vector<double >v1;
	cin>>v1;
	cout<<v1<<endl;
	cout<<"Please input string vector"<<endl;
	vector<char >v2;
	cin>>v2;
	cout<<v2<<endl;
} 


void test2(){
	cout<<"Please input integer vector Vector_1"<<endl;
	vector<int >v;
	cin>>v;
	vector<int >v2;
	v2=v;
	cout<<"赋值Vector_2为Vector_1:  Vector_2= "<<v2<<endl;
} 


void test3(){

	vector<int >v;
	cin>>v;
	cout<<"请输入想要查找的数"<<endl;
	int n;
	cin>>n;
	cout<<"位置为:"<<v.Find(n)+1<<endl;
} 


void test4(){

	vector<int >v1,v2;
	cout<<"请分别输入两个向量"<<endl;
	cin>>v1>>v2;
	cout<<"两个向量的和为:"<<v1+v2<<endl;
} 


void test5(){

	vector<int >v1,v2;
	cout<<"请分别输入两个向量"<<endl;
	cin>>v1>>v2;
	cout<<"两个向量的差为:"<<v1-v2<<endl;
} 


void test6(){

	vector<int >v1,v2;
	cout<<"请输入两个向量"<<endl;
	cin>>v1>>v2;
	cout<<"两个向量的点积为:"<<v1*v2<<endl;
} 


void test7(){

	vector<double >v;
	cout<<"输入一个向量:"<<endl;
	cin>>v;
	cout<<"向量的模为:"<<v.norm(v)<<endl;  
}


void test8(){

	vector<double >v1,v2;
	cout<<"请输入一个向量:"<<endl;
	cin>>v1;
	v2=v1.unit(v1);
//	cout<<"向量的单位向量为:"<<v2<<endl;
} 


void test9(){
	cout<<"求叉乘"<<endl;
	vector<int >v1,v2,v3;
	cout<<"请输入两个三维向量:"<<endl;
	cin>>v1>>v2;
    v3=Vector_Cross_Product(v1,v2);
	cout<<"两个向量的叉积为:"<<v3<<endl;
}


void test10(){

	vector<int >v1,v2;
	cout<<"请输入两个向量:"<<endl;
	cin>>v1>>v2;
	if(Perpendicular(v1,v2))
        cout<<"两个向量垂直"<<endl;
    else
        cout<<"两个向量不垂直"<<endl;		
} 


void test11(){
	vector<int >v1,v2;
	cout<<"请输入两个向量:"<<endl;
	cin>>v1>>v2;
	if(Parallel(v1,v2))
        cout<<"两个向量平行"<<endl;
    else
        cout<<"两个向量不平行"<<endl;	
}





int main(int argc, char** argv) {
	cout<<"*************Vector功能选择**************"<<endl;
	void (*f[])() = {test1, test2, test3, test4, test5, test6,test7,test8,test9,test10,test11};
	int choice, n = sizeof(f)/sizeof(*f);
	
	while(1){
		cout << "\nVector (1--" << n << ", 0-quit): ";
		cout<<"1. I/O操作 "<<endl;
		cout<<"2.向量的赋值 "<<endl;
		cout<<"3.查找向量分量位置  "<<endl;
		cout<<"4.向量的加法"<<endl;
		cout<<"5.向量的减法"<<endl;
		cout<<"6.向量的点积"<<endl;
		cout<<"7.向量的模 "<<endl;
		cout<<"8.向量的单位化 "<<endl;
		cout<<"9.向量的叉积"<<endl;
		cout<<"10.判断向量垂直"<<endl;
		cout<<"11.判断向量平行"<<endl;
		//choice = getche() - '0';
		cin>>choice;
		if(choice <= 0) break;
		if(choice <= n) f[choice-1]();
	}
	return 0;
}





参考资料:

http://blog.csdn.net/typecool/article/details/5843208

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值