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

175

被折叠的 条评论
为什么被折叠?



