Whenever I assign an already declared Matrix to somethnig else my program exits unexpectedly.
I really don’t know why this happens, I was under the impression that leaving assignment operators for the compiler to generate was the best thing to do unless you absolutely had to overload it, which makes me think there’s something wrong with my constructor or something?
Example:
Matrix rotation = rotationMatrix3(Y, degToRad(20.0f));
Vector3 left = rotation * direction_;
rotation = rotationMatrix3(Y, degToRad(-20.0f)); //crash
Vector3 right = rotation * direction_;
Here’s my Matrix class:
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");
}
}
Drop that impression. Those freebies from the language are rarely the “right” thing to do. You have a raw pointer
float* values_;in your class. You absolutely have to overload the copy constructor and the assignment operator here.