C ++中的基本类设计,处理共同依赖的类

时间:2014-09-12 16:05:39

标签: c++ class

我有两个类,一个3D矢量类(Vector3),其数组为3个浮点数作为其成员(float [3]),以及一个3×3矩阵类,它将这些矢量中的3个存储在另一个数组中(Vector3 [3] ])。我的vector类要求矩阵类绕轴旋转,而我的矩阵类需要所有东西的向量。我正在使用前向声明和指针来处理它,就像这个问题:What is the best way to deal with co-dependent classes in C++?,但必须有一个更好的方法来设计它以完全避免这种情况。目前我在我的矩阵头文件中声明了一个指向Vector3的指针,然后在我的实现文件中用new初始化它,但这感觉很笨拙。关于如何解决这个问题的任何指针(没有双关语)? 编辑:我使用矢量类来表示我想围绕任意轴旋转的3D点。

我希望它可以使用的代码:

    //Vector3.h

    #include "Matrix3.h"
    class Matrix3;

    class Vector3 {
      float xyz[3];
    };

    //Vector3.cpp

    Vector3 Vector3::rotatePoint(Vector3 o, Vector3 a,  float theta) {

Vector3 point = (*this);
Vector3 x = Vector3(1,0,0);
Vector3 y = Vector3(0,1,0);
Vector3 z = Vector3(0,0,1);

// Create new coordinate system
Vector3 new_coord[4];
new_coord[0] = o;
new_coord[1] = a.normalize();

unsigned closer_to;
if (a*x < a*y) {
    new_coord[2] = (a % x).normalize();
    closer_to = 0; // x
}
else {
    new_coord[2] = (a % y).normalize();
    closer_to = 1; // y
}
new_coord[3] = (a % new_coord[2]).normalize();

// Transform point to new coord system
Matrix3 trans_matrix = Matrix3(new_coord[0], new_coord[1], new_coord[2]);
point = trans_matrix*(point - o);

// Rotate about a by theta degrees
Matrix3 r_m(closer_to, theta);
point = r_m*point;

//Transform back to original coord system
point = (trans_matrix.inverse()*point) + o;
return point;
}        
    //Matrix3.h

    #include "Vector3.h"

    class Vector3;

    class Matrix3 {
       Vector3 rows[3];
    }

我用来使其工作的代码:

    //Vector3.h

    class Matrix3;

    class Vector3 {
      float xyz[3];
    };

    //Matrix3.h

    #include "Vector3.h"

    class Vector3;

    class Matrix3 {
       Vector3 *rows;
    }

    //Matrix3.cpp

    Matrix3::Matrix3() {
        rows = new V3[3];
    }

2 个答案:

答案 0 :(得分:0)

我接受了@n.m给出的建议。和@Chris Dodd&只是从我的Vector标题中删除了Matrix3 include,并进入了我的Vector实现文件,如下所示:

    //Vector3.h

    class Vector3 {
        float xyz[3];
    }

    //Vector.cpp

    #include "Vector3.h"
    #include "Matrix3.h"

    //Matrix3.h

    #include "Vector3.h"
    class Vector3;

    class Matrix3 {   
        Vector3 rows[3];
    }

    //Matrix3.cpp

    #include "Matrix3.h"

答案 1 :(得分:0)

由于你正在处理向量和矩阵,你可以定义一个矩阵类,其中包含维度的模板(也许是元素类型) - 然后,向量类(取决于向量的类型)是一个矩阵其中一个维度= 1.如果这样做,您最终只会得到一个类,一组代码以及执行所需操作所需的所有功能。您可以避免任何类间依赖关系,因为您只有一个类!

该类本身看起来像这样:

template<unsigned m, unsigned n, typename T = float>
class matrix {
    T e[m * n];
public:
   T* operator [](unsigned i) { return e + i; }
   T * const operator [](unsigned i) const { return e + i; }
   /* repeat for -, *, / -- same pattern */
   matrix<m,n>& operator += (matrix<m,n> const& a) {
        for (unsigned i = 0; i < m * n; ++i) e[i] += a.e[i];
        return *this;
   }
};

然后你应该定义任何不在类外使用相同大小的矩阵的函数(这就是为什么我们有[]运算符)。请注意,*和/运算符适用于所有元素,不计算通常的矩阵 - 矩阵乘法或矩阵 - 矩阵除法。相反,您需要具有反转函数和乘法函数。

template<unsigned m, unsigned n, unsigned k>
matrix<m,k> const multiply(matrix<m,n> const& a, matrix<n,k> const& b);

template<unsigned m>
matrix<m,m> const invert(matrix<m,m> const&);

template<unsigned m, unsigned n>
matrix<n,m> const transpose(matrix<m,n> const&);

请注意,如果您有一种反转通用非方阵的方法,我不知道它,上面的模板只适用于方阵。填写我作为练习留给您的函数的代码。

要获得3矢量和3x3矩阵,您可以将它们设置为:

typedef matrix<3,1,float> vector3f;
typedef matrix<3,3,float> matrix3x3f;

请记住添加比较运算符以及您需要的任何其他内容。

如果您愿意,还可以添加矩阵标量和标量矩阵运算符和函数(比如,为矩阵中的所有元素添加标量)。

如果想要更好地控制[]运算符中的元素,可以使用向量作为基类,然后将矩阵定义为向量向量。这将给你相同的优势,但可能更容易适合你的心态(很多人认为矢量和矩阵是不同的类型)。