每当我将已经声明的Matrix
分配给somethnig,我的程序意外退出。
我真的不知道为什么会发生这种情况,我的印象是让编译器生成赋值运算符是最好的事情,除非你绝对不得不重载它,这让我觉得我的错了构造函数还是什么?
示例:
Matrix rotation = rotationMatrix3(Y, degToRad(20.0f));
Vector3 left = rotation * direction_;
rotation = rotationMatrix3(Y, degToRad(-20.0f)); //crash
Vector3 right = rotation * direction_;
这是我的Matrix课程:
Matrix.h
enum Axis {
X, Y, Z,
};
class Matrix {
public:
Matrix(int cols, int rows);
Matrix(int cols, int rows, const float values[]);
~Matrix();
float& operator()(int col, int row);
float operator()(int col, int row) const;
inline int cols() const { return cols_; }
inline int rows() const { return rows_; }
private:
int cols_, rows_;
float* values_;
};
Vector3 operator*(const Matrix& m, const Vector3& v);
Matrix rotationMatrix3(int axis, float rads);
Matrix.cpp
Matrix::Matrix(int cols, int rows) : cols_(cols), rows_(rows), values_(NULL) {
values_ = new float[rows_ * cols_];
}
Matrix::Matrix(int cols, int rows, const float values[]) : cols_(cols), rows_(rows), values_(NULL) {
values_ = new float[rows_ * cols_];
for(int c = 0; c < cols; ++c) {
for(int r = 0; r < rows; ++r) {
(*this)(c, r) = values[r * cols + c];
}
}
}
Matrix::~Matrix() {
delete [] values_;
}
float& Matrix::operator()(int col, int row) {
return values_[row * cols_ + col];
}
float Matrix::operator()(int col, int row) const {
return values_[row * cols_ + col];
}
Vector3 operator*(const Matrix& m, const Vector3& v) {
if(m.cols() != 3) {
throw std::logic_error("Matrix must have only 3 cols");
}
Vector3 result;
result.x = m(0, 0) * v.x + m(1, 0) * v.y + m(2, 0) * v.z;
result.y = m(0, 1) * v.x + m(1, 1) * v.y + m(2, 1) * v.z;
result.z = m(0, 2) * v.x + m(1, 2) * v.y + m(2, 2) * v.z;
return result;
}
Matrix rotationMatrix3(int axis, float rads) {
float c = static_cast<float>(cos(rads));
float s = static_cast<float>(sin(rads));
if(axis == X) {
const float mat[] = { 1.0f, 0.0f, 0.0f,
0.0f, c, -s,
0.0f, s, c };
return Matrix(3, 3, mat);
} else if(axis == Y) {
const float mat[] = { c, 0.0f, s,
0.0f, 1.0f, 0.0f,
-s, 0.0f, c };
return Matrix(3, 3, mat);
} else if(axis == Z) {
const float mat[] = { c, -s, 0.0f,
s, c, 0.0f,
0.0f, 0.0f, 1.0f };
return Matrix(3, 3, mat);
} else {
throw std::logic_error("Unknown axis");
}
}
答案 0 :(得分:2)
是的,制作一个带矩阵的复制构造函数。否则,您将复制指针values_
,该指针随后将在原始返回值中删除,该指针会立即退出范围。
我给你的建议......你显然是在创建3D课程。不要为此制作任意大小的矩阵类。只需制作一个基本的4x4均匀矩阵(如果必须,则为4x3或3x3)。硬编码。单个数组值 - 无动态分配。节省大量时间,堆碎片和烦人的健全测试。你永远不会用5x17矩阵或其他什么来运行这个类。所以不要为它编码。
您通常需要2d,3d或4d矢量以及3d或4d方阵。就这样。所以上课:
Vector2
Vector3
Vector4
Matrix3
Matrix4
答案 1 :(得分:2)
我的印象是,为编译器生成赋值运算符是最好的事情,除非你绝对不得不重载它,这让我觉得我的构造函数有什么问题?
放弃这种印象。那些语言的免费赠品很少是“正确”的事情。您的班级中有一个原始指针float* values_;
。你绝对必须在这里重载复制构造函数和赋值运算符。