Vector class (1)[1]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 neverfly 的 blog

referrence:
jim blinn, "optimizing c++ vector expression", in ieee database
kenneth i. joy, "the vector data type", http://graphics.cs.ucdavis.edu/cppnotes/homepage.html

part i: on constructor:
"all classes should have a copy constructor and an assignment operator."
that means, we should add two functions:
"vector(const vector&); and vecotr& operator=(const vector&);"
together with
"vector(const double, const double, const double =0.0)"

原因是安全并且方便 (参考effective c++第三章, rule 11)
and consider that
vecotr& operator=(const vector&)
the input and output of operator is the same.

part ii: on output and serialize
暂时不管他

part iii operator calling
试试严格遵守"没有重复代码的规定"

vector& operator+=(const vector& v2)
{
 _x+=v2._x; _y+=v2._y; _z+=v2._z;
 return *this;
}
int operator== (const vector& v1, const vector &v2)
{
 if((v1._x==v2._x)&&(v1._y==v2._y)&&(v1._z==v2._z))
    return true;
 else
    return false;
}
在这个基础上,定义
vector& operator+(const vector& v1, const vector &v2)
{
 return vector(a) +=b;
}
int operator!= (const vector& v1, const vector &v2)
{
 return(!(v1==v2));
}
看起来不错,但实际上operator+定义的不好。因为这样增加了一个vector(a)的创建对象的开销。
我敢肯定matlab不会这样干的。希望下次可以研究一下matlab的早期代码。

part iv 随心所欲的计算

part of the vast popularity of c++ is its class structure and operator overloading features
that allow the definition of mathematical operations for many class. we should know we can
make the c++ act as matlab!

接着讨论operator+.如果我们不搞得那么花哨的话我们可以定义operator+的返回值是vector 而不是vector&
注意opertator+ 与operator=的情况是完全不一样的!
vector operator+ (const vector& v1, const vector& v2)
{
 vector vv;
 vv._x = v1._x+v2._x;
 vv._y = v1._y+v2._y;
 vv._z = v1._z+v2._z;
 return(vv);
}

这样可以定义 *, /,-,+.
其他的,matlab里有.*,./,.-,.+.可以试试
另外,定义 vector cross(const vector& v1, const vector& v2);
double dot(const vector& v1, const vector& v2);
void vector::normalize();
double vector::length();
最后,考虑operator重载,vector operator+(float f1)等等。
当然,要想像matlab一样随心所欲,还有三件事
1.试试模板之类的东西。matlab可以不管int double 通吃的。
2.和矩阵的计算,接口
3.matlab 可以 d = [a,b,c]. c++好像只能d = vector(a,b,c)了。凑合着用了
这三条,以后再说吧.

part v 编译错误

这玩意极其让人讨厌。#是万恶之源。std更是把这种罪恶推到了极点。
多用const吧。

1. we should know the difference between const char *p (*p='c' is not allowed)
and char* const p (p++ is not allowed);
2. we should know the reason why vector dot(const vector&, const vector &)
instead of vector dot(vector&,vector &). yes, one reason is it is more safe.
but another reason, if we define vector dot(vector&, vector &), we will get
errors when using: a = dot(v1+v2,v3). the compiler will not allow you to change
(v1 + v2)!
3. do not forget to declare a const function: double length()const; will not
change the data members of the class.

part vi 效率
c++运行比较慢就在于创建对象的开销。 一个奇怪的现象是c++大规模矩阵计算未必赶得上matlab.
至于其他的软件,至少我觉得photoshop远远比一般的图像处理程序快的多。优化还是很重要的啊。
上面的vector实现比较费时的地方是每个operator+里面都要创建一个vector对象
然而,一个tricky的做法是采用"容器",而不是数据对象

class sum{
const vector &l;
const vector &r;
public:
sum(const vector& linit, const vector& rinit):l(linit),r(rinit){;}
float operator[](int i)const {return l[i]+r[i];} 
}

void vector::evaluate(const sum& e){
 v[0]=e[0];v[1]=e[1];v[2]=e[2];
}
sum operator+(const vector& a,const vector& b){ 
 return sum(a,b);
}

恩,这种东西真难维护。 :-p
不过呢,用visitor模式,定义void vector::evaluate(const function& e),
然后用function 派生出各个类, sum, product....,各个类实现虚函数
operator[]。比如sum::operator[](int i)是{return l[i]+r[i]}
而product::operator[](int i)则是{return s*v[i]}.
漂亮把?
----yes, but.... do you know the cost of virtual function?
根据berlin的结果,用visitor模式的效率还不如最土的办法。:-(

在effective c++中,41号条款告诉我们,
"如果类型t不影响类的行为t,你可以使用模板。如果t影响行为,你就需要虚函数,从而要使用继承。"
能不能把上面的trick用template 表示呢? 模板的效率好像还不错,想想stl就知道了
ok,let's go

//sum<l,r>
template<class lt,class rt>
class sum{
const lt &l;
const rt &r;
public:
sum(const lt& linit, const rt& rinit):l(linit),r(rinit){;}
float operator[](int i)const{return l[i]+r[i];} 
};

//product<v>
template<class vt>
class product{
float s;
const vt& v;
public:
product(const float sinit,const vt& vinit):s(sinit),v(vinit){;}
float operator[](int i)const{return s*v[i];}
};

// class vector
class vector{
...
template <class t>
vector(const t& e){
 evaluate(e);

本文关键:Vector class (1)
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top