我有一个类Matrix和另一个我想要使用Matrix的类Camera。我的Matrix类看起来像这样:
class Matrix4f {
public:
Matrix4f() {
this->setMatrix(EMPTY);
}
Matrix4f(Matrix4f &m2) {
this->setMatrix(m2.matrix);
}
static Matrix4f& Matrix4f::identity() {
Matrix4f& identity = Matrix4f() ;
identity.setMatrix(IDENTITY);
return identity;
}
void setMatrix(float f[4][4]) {
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
this->matrix[r][c] = f[r][c];
}
}
}
Matrix4f& operator=(const Matrix4f &m2) {
this->setMatrix(m2.matrix);
}
private:
float matrix[4][4];
static float EMPTY[4][4] = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
}; // initialize an empty array (all zeros);
static float IDENTIY[4][4] = {
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 }
}; // initialize a identity (array)
}
我在相机课上有这个:
class Camera {
public:
Camera() {
this->calculateProjection();
}
Matrix4f* getProjection() {
return this->projection;
}
private:
Matrix4f* projection;
Matrix4f* calculateProjection() {
this->projection = &Matrix4f::identity();
// modify this->projection...
return this->projection;
}
}
当我尝试创建一个Camera实例然后得到它的投影时,我得到的东西看起来像一个被破坏的对象(矩阵完全被填充到大的负数)。
我真的很困惑导致我的代码行为异常。
我相当肯定它会处理编译器自动删除的引用,我认为它处理的是单位矩阵,但它并没有真正有意义。
不应该将单位矩阵复制到投影矩阵中,因此如果单位矩阵被垃圾收集也不重要吗?
我发现我实际上可以使这个代码工作
使单位矩阵创建一个新的Matrix4f()并返回该OR使得getProjection()返回calculateProjection()。
问题是,我真的不想做其中任何一个。
我不想让身份构建一个新的Matrix4f,因为那时我必须处理它的破坏,我不希望getProjection()调用calculateProjection(),因为该方法很昂贵,并且实际上只应调用一次,因为Projection矩阵永远不会改变。
答案 0 :(得分:2)
您
Matrix4f& Matrix4f::identity() {
Matrix4f& identity = Matrix4f() ;
identity.setMatrix(IDENTITY);
return identity;
}
返回对本地对象的引用。一旦identity()退出,对象就消失了。
您需要在堆上分配它然后返回它。
或者在类Camera
中声明一个矩阵 ...
private:
Matrix4f projection;
Matrix4f& calculateProjection() {
... modify ...
return this->projection;
}
...
答案 1 :(得分:1)
我是否误解了指针是如何工作的?
也许。您的代码有几个我可以看到的问题:
Matrix4f& Matrix4f::identity() {
Matrix4f& identity = Matrix4f() ;
identity.setMatrix(IDENTITY);
return identity;
}
这会创建一个临时对象及其引用(引用称为identity
)。我不确定临时对象是在Matrix4f& identity = Matrix4f() ;
之后还是在函数返回时被销毁 - 但无论如何,临时对象在函数返回之前被销毁,因此该函数返回对已经对象的引用破坏。
this->projection = &Matrix4f::identity();
然后将 this->projection
设置为已销毁的临时对象的地址。
稍后,您尝试访问被销毁的临时对象,并且不出所料地获取垃圾数据。
此外,identity
(函数)不是静态的,因此您无法将其称为Matrix4f::identity()
。