Bingo, Computer Graphics & Game Developer
我将我尝试的心路历程都记录在了这里。
这里的快速实质上是代表了代码书写的高效率。在重造数据结构里线性表的轮子的时候,遇到了需要构造NxM的矩阵需求,因为NxM可以动态构建出来,这没什么。
如下,可以非常方便的造一个简单的NxM的矩阵轮子出来
class t3Matrix
{
public:
// 构造函数参数里给出行列即可
t3Matrix(int row, int col):col(col), row(row)
{
m = new int*[row]();
for(int i = 0; i < row; i++)
m[i] = new int[col]();
}
~t3Matrix()
{
for(int i = 0; i < row; i++)
delete[] m[i];
delete[] m;
}
int **m;
int col, row;
};
问题来了,如何赋值,倘若是以往的2x2, 3x3事实上都是好解决的。
void t3Matrix2x2::create(int a00, int a01, int a10, int a11)
{
// do something...
}
void t3Matrix3x3::create(int a00, int a01, int a02, int a10, int a11, int a12)
{
// do something...
}
// etc...
实际使用的时候这样的方法也不免为一个好决策。这里我颇受Eigen的影响, 他的矩阵初始化办法颇为简便易读,他是这样的。
void main()
{
// NxM
t3Matrix m(2, 3);
// core!
m << 1, 2,
3, 4,
5, 6;
}
这才像话,立马动手抄,但是Eigen过于庞大,也只能依样画葫芦尝试着去实现。
尝试1
移位运算符与stream联系非常迫切,兴许有效。这里我尝试着这样去试着使用istream,ostream配合着完成这样的初始化。
class t3Matrix
{
public:
t3Matrix();
~t3Matrix();
};
ostream& operator<<(ostream& os, t3Matrix& m);
istream& operator>>(istream& is, t3Matrix& m);
思来想去,我最多能够做到使用cin,cout为矩阵初始化和输出,并不能在代码中实现初始化动作。
void fuck()
{
t3Matrix m(n, m);
// 标准输入初始化矩阵
cin >> m;
// 抛却m.print()方式标准输出
cout << m;
}
然而这并没有什么卵用,期间我甚至尝试着让t3Matrix继承
std::ostream。注意!OSX下XCode不会对以下代码报错
class A:public std::ostream
{
public:
// 如若不为ostream构造,那么你将面临两次调用matrix析构函数的问题(Windows上VS编译无法通过)
// 解决办法是写为ostream(NULL)提供一个streambuf参数即可,当然也可以给NULL
A(){}
// 会被二次调用
~A(){}
};
class A:public std::ostream
{
public:
// 运行正常
A():std::ostream(NULL){}
~A(){}
};
尝试2
这回另辟蹊径,想起了重载逗号运算符。重载这个运算符实在是太少见了,以至于我和同学说起时,惊讶的反应:这**玩意也要重载?
其实需求很明显只要m << 1, 2, 3, 4;
能够一路正确的读取即可,<<
的优先级高于,
,加上从左到右的运算顺序。
所以只要满足m << 1
的返回值能够与重载,
的运算符左参数相符,那么其实就是t3Matrix自身了。
以下写法已证实可行
class t3Matrix
{
public:
// ...
t3Matrix& operator,(int value)
{
// 赋该value到正确的位置
// do something...
return *this;
}
t3Matrix& operator<<(int value)
{
// 赋该value到正确的位置
// do something...
return *this;
}
};
void main()
{
t3Matrix m(2, 3);
m << 1, 2,
3, 4,
5, 6;
}
其实难度不在于”<<”的重载,而是想到”,”的重载才是
已更新至t3DataStructures