c++ - 矩阵类的转置方法
问题描述
我目前正在研究一个矩阵类,我无法决定哪种方法最适合处理矩阵转置。
起初我做了经典的方式:
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++ 的“内存管理”方面还是很陌生,而且我真的不知道哪个方法在“良好实践”方面更好......
解决方案
出于几个原因,您的第一个构造更可取,我在下面讨论过。仅供参考:您可能会发现返回值优化也很有趣。
把事情简单化
第二种解决方案是不必要的复杂。您已经用 9 行代码替换了本质上是 4 行代码的内容。您还介绍了另一个 for 循环和堆内存的使用。第二种解决方案速度较慢,几乎按照定义,因为您正在做更多的工作。
使用堆栈
在使用临时数据结构时,正如您在第二个示例中所做的那样,您应该更喜欢堆栈内存。引入额外的内存分配会引入您不需要的开销。
避免令人惊讶的行为+副作用
您的第二个构造修改了您的实例,对于这种类型的转换可能会令人惊讶。
提示
使用 C++ 的一些额外提示。
关于上面的第三点,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;
}
推荐阅读
- azure-devops - Azure Devops 管道能否更新 Azure 应用配置
- excel - 数据验证 - 根据表中的值动态更新
- php - 使用比较或 || 输出字符串不是布尔值 操作员
- python - 将 SciPy 优化应用于拟合的 sci-kit 模型
- swift - tableView.setContentOffset(_, animated:) 在 beginUpdates() 之后不起作用
- python - Python网页抓取(request.get)无法获取目标网页
- python - 尽管在一个范围内迭代,但字符串索引超出范围
- python - Pandas - 如果匹配条件和在其他列中定义的时间范围,则为行分配值
- c - 为什么此代码击败 rint() 以及如何保护它免受 -ffast-math 和朋友的影响?
- excel - 在 VBA 中选择和格式化边框