我目前正在研究矩阵类,无法确定哪种方法最适合处理矩阵转置。
起初我采用经典方式:
Matrix Matrix::Transpose()
{
Matrix M(m_cols, m_rows);
for(int i=0; i < m_rows; ++i)
{
for(int j=0; j < m_cols; ++j)
{
M(j,i) = this->m_matrix[i][j];
}
}
return M;
}
但是转而想一想,我想知道这种方法在内存管理方面是否更好:
Matrix& Matrix::Transpose()
{
std::unique_ptr<Matrix> M(new Matrix(*this));
m_matrix.resize(m_cols);
for(unsigned long i = 0; i < m_matrix.size(); ++i)
{
m_matrix[i].resize(m_rows, 0.0);
}
m_rows = M->Get_Cols();
m_cols = M->Get_Rows();
for(unsigned long i=0; i < M->Get_Rows(); ++i)
{
for(unsigned long j=0; j < M->Get_Cols(); ++j)
{
this->m_matrix[j][i] = (*M)(i,j);
}
}
return *this;
}
现在这两种方法都可以使用,但是我对C ++的“内存管理”方面还很陌生,我无法真正断定哪种方法在“良好实践”方面更好。
答案 0 :(得分:1)
由于以下几个原因,您的第一个结构是可取的,下面将对此进行讨论。仅供参考:您可能还会发现return value optimization有趣。
第二种解决方案不必要地复杂。您已经用9行代码替换了实质上的4行代码。您还介绍了另一个for循环和堆内存的使用。第二种解决方案速度较慢,几乎可以肯定是这样,因为您正在做更多工作。
在处理临时数据结构时(如第二个示例中所述),您应该更喜欢堆栈存储器。引入额外的内存分配会带来不必要的开销。
您的第二个构造会修改您的实例,对于这种类型的转换而言,这可能令人惊讶。
使用C ++的一些其他提示。
this->
unless necessary-这是隐含的const
-请参见Cpp Core Guidelines 关于以上第三点,private
关键字适用于类型级别,而不适用于实例。看一下下面的代码。您认为输出是什么?注意,在我们自己的类方法中,我们可以引用另一个实例的私有变量。 action
方法被标记为const-因此我们知道它不会影响我们的实例,但是参数是一个我们可以可以修改的可变实例。
#include <iostream>
using namespace std;
class Test
{
public:
Test() = default;
~Test() = default;
int x;
int y;
void setZ()
{
m_z = x * y;
}
void action(Test& other) const
{
other.m_z = m_z;
}
int z() const { return m_z; }
private:
int m_z;
};
int main()
{
Test a;
Test b;
a.x = 5;
a.y = 3;
a.setZ();
a.action(b);
cout << b.z() << endl;
return 0;
}