读书人

有些凌乱,该怎么处理

发布时间: 2012-04-23 13:17:38 作者: rapoo

有些凌乱
书上写了个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 中的几乎一模一样啊,怎么也不说明出处啊?
[解决办法]
第一段会内存泄漏。

读书人网 >C++

热点推荐