我误解了指针是如何工作的吗?

时间:2016-09-30 04:07:30

标签: c++ class pointers reference

我有一个类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矩阵永远不会改变。

2 个答案:

答案 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()