有些凌乱
书上写了个Array的实现,本意是想有这种效果
Array<double> a(3),b(3);a=1.2*a+a*b;
不难的,写了这些就可以实现了
- C/C++ code
template<class T>class SArray{//Array的Simple实现 private: T* storage; size_t storage_size;protected: void init(){//初始化为T() for(size_t i=0;i<storage_size;++i){ storage[i]=T(); } } void copy(const SArray& s){//从s拷贝 assert(storage_size==s.storage_size); cout<<"copy\n"; for(size_t i=0;i<storage_size;++i){ storage[i]=*(s.storage+i); } } public: size_t size()const{return storage_size;} explicit SArray(size_t t):storage_size(t),storage(new T[t]){init();} SArray(const SArray& s){ cout<<"copy cons\n"; copy(s); } SArray& operator=(const SArray& s){ cout<<"operator =\n"; if(&s!=this){ copy(s); } return *this; } T operator[](size_t i)const{//做为右值调用这个 ,读操作,常量 a[0]=a[1]+a[2](a[1],a[2]调用这个重载) return storage[i]; } T& operator[](size_t i){//做为左值调用这个 ,写操作,变量 a[0]=a[1]+a[2](a[0]调用这个重载) return storage[i]; } template<class TT> friend SArray<TT> operator+(const SArray<TT>& op1,const SArray<TT>& op2);//两者相加的友元声明 SArray& operator+=(const SArray& s){//+= for(size_t i=0;i<s.size();i++){ storage[i]+=s[i]; } return *this; } SArray& operator*=(const SArray& s){//*= for(size_t i=0;i<s.size();i++){ storage[i]*=s[i]; } return *this; } SArray& operator*=(const T& s){//*=一个常数 for(size_t i=0;i<size();i++){ storage[i]*=s; } return *this; } };template<class T>ostream& operator<<(ostream& ofile,const SArray<T>& s){ for(size_t i=0;i<s.size();++i){ ofile<<s[i]<<" "; } return ofile<<endl;} template<class T>SArray<T> operator+(const SArray<T>& op1,const SArray<T>& op2){ SArray<T> ret(op1.size()); for(size_t i=0;i<op1.size();++i){ ret[i]=*(op1.storage+i)+*(op2.storage+i); } return ret;} template<class T>SArray<T> operator*(const SArray<T>& op1,const SArray<T>& op2){ SArray<T> ret(op1.size()); for(size_t i=0;i<op1.size();++i){ ret[i]=op1[i]*op2[i]; } return ret;} template<class T>SArray<T> operator*(T const& s,const SArray<T>& a){ SArray<T> ret(a.size()); for(size_t i=0;i<a.size();++i){ ret[i]=s*a[i]; } return ret; } template<class T>SArray<T> operator*(const SArray<T>& a,T const& s){ return s*a; } ok!!
SArray<double> a(3),b(3);a=1.2*a+a*b;
但效率很有问题,会至少产生3个临时对象
1.2*a一个,a*b一个,两者相加又有一个,会有大量开销,尤其是SArray大小很大,比如1000个double,
于是就想a=1.2*a+a*b的时候由模板产生,静态编译期就确定做什么操作,使得效果类似于这样
for(size_t i=0;i<a.size();i++){a[i]=1.2*a[i]+a[i]*b[i];}不产生临时对象,减少大量开销,于是有了下面的代码
- C/C++ code
template<typename T>class A_Traits;template<class T,class OP1,class OP2>class A_Add{private: typename A_Traits<OP1>::ExprRef op1; typename A_Traits<OP2>::ExprRef op2;public: A_Add(const OP1& a,const OP2& b):op1(a),op2(b){} T operator[](size_t idx)const {return op1[idx]+op2[idx];} size_t size()const{ assert(op1.size()==0 || op2.size()==0 || op1.size()==op2.size()); return op1.size()!=0 ? op1.size() : op2.size(); } }; template<typename T,typename OP1,typename OP2>class A_Mult{private: typename A_Traits<OP1>::ExprRef op1; typename A_Traits<OP2>::ExprRef op2;public: A_Mult(const OP1& a,const OP2& b):op1(a),op2(b){} T operator[](size_t idx)const{return op1[idx]*op2[idx];} size_t size()const{ assert(op1.size()==0 || op2.size()==0 || op1.size()==op2.size());//为0说明是A_Scalar类型 return op1.size()!=0 ? op1.size() : op2.size();//如果op1的大小是0,返回op2的大小 } }; template<typename T>class A_Scalar{private: T const& s;public: A_Scalar(T const& v):s(v){} T operator[](size_t)const{return s;} size_t size()const{ return 0; } }; template<typename T>class A_Traits{public: typedef T const& ExprRef;}; template<typename T>class A_Traits<A_Scalar<T> >{//如果是A_Scalar<T> 则ExprRef是A_Scalar<T> 而不是 A_Scalar<T> const& public: typedef A_Scalar<T> ExprRef;}; template<typename T,typename Rep=SArray<T> >class Array{private: Rep expr_rep;public: explicit Array(size_t s):expr_rep(s){}//forbid convince int type to array type Array(const Rep& rb):expr_rep(rb){} size_t size()const{return expr_rep.size();} Array& operator=(Array const & b){ assert(size()==b.size()); for(size_t i=0;i<size();i++){ expr_rep[i]=b[i]; } return *this; } template<typename T2,typename Rep2> Array& operator=(Array<T2,Rep2> const & b){//从其他类型来构造 assert(size()==b.size()); for(size_t i=0;i<size();i++){ expr_rep[i]=b[i]; } return *this; } T operator[](size_t idx)const{//右值 assert(idx>=0 && idx<size()); return expr_rep[idx]; } T& operator[](size_t idx){//左值 assert(idx>=0 && idx<size()); return expr_rep[idx]; } Rep const& rep()const{return expr_rep;}//right value Rep& rep(){return expr_rep;}//left value};template<typename T,typename R1,typename R2>Array<T,A_Add<T,R1,R2> > operator+(const Array<T,R1>& a,const Array<T,R2>& b){//array + array//从此处开始,被嵌套得有些凌乱,有些晕 return Array<T,A_Add<T,R1,R2> > (A_Add<T,R1,R2>(a.rep(),b.rep()));} template<typename T,typename R1,typename R2>Array<T,A_Mult<T,R1,R2> > operator*(const Array<T,R1>& a,const Array<T,R2>& b){//array * array return Array<T,A_Mult<T,R1,R2> > (A_Mult<T,R1,R2>(a.rep(),b.rep()));} template<typename T,typename R>Array<T,A_Mult<T,A_Scalar<T>,R> > operator*(const T& s,const Array<T,R>& b){//scalar * array return Array<T,A_Mult<T,A_Scalar<T>,R> >(A_Mult<T,A_Scalar<T>,R>(A_Scalar<T>(s),b.rep()));} template<typename T,typename R>Array<T,A_Mult<T,A_Scalar<T>,R> > operator*(const Array<T,R>& b,const T& s){//scalar * array return s*b;}template<typename T,typename R>Array<T,A_Add<T,A_Scalar<T>,R> > operator+(const T& s,const Array<T,R>& b){ return Array<T,A_Add<T,A_Scalar<T>,R> >(A_Add<T,A_Scalar<T>,R>(A_Scalar<T>(s),b.rep()));} template<typename T,typename R>Array<T,A_Add<T,A_Scalar<T>,R> > operator+(const Array<T,R>& b,const T& s){ return s+b;} template<typename T>ostream& operator<<(ostream& ofile,const Array<T>& a){ return ofile<<a.rep();}
主函数为
- C/C++ code
int main(){ Array<double> a1(3),a2(3); a1[0]=1;a1[1]=2;a1[2]=3; a2[0]=3;a2[1]=2;a2[2]=1; a1=1.2*a1+a1*a2; cout<<a1; system("pause");} [解决办法]
楼主的代码和 C++ Templates : The Complete Guide 一书中第 18 章 Expression Templates 中的几乎一模一样啊,怎么也不说明出处啊?
[解决办法]
第一段会内存泄漏。