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

C++ C+中的基本类设计+;,处理共同依赖类,c++,class,C++,Class,我有两个类,一个是3D向量类(Vector3),它的成员是3个浮点数组(float[3]),另一个是3乘3矩阵类,它将这些向量中的3个存储在另一个数组中(Vector3[3])。我的vector类要求matrix类绕轴旋转,而matrix类要求所有东西都有向量。我使用了前向声明和指针来处理它,就像在这个问题中:,但必须有更好的方法来设计它,以完全避免这种情况。目前,我在我的矩阵头文件中声明了一个指向Vector3的指针,然后在我的实现文件中用new初始化它,但这感觉很笨拙。有没有关于如何解决这个

我有两个类,一个是3D向量类(Vector3),它的成员是3个浮点数组(float[3]),另一个是3乘3矩阵类,它将这些向量中的3个存储在另一个数组中(Vector3[3])。我的vector类要求matrix类绕轴旋转,而matrix类要求所有东西都有向量。我使用了前向声明和指针来处理它,就像在这个问题中:,但必须有更好的方法来设计它,以完全避免这种情况。目前,我在我的矩阵头文件中声明了一个指向Vector3的指针,然后在我的实现文件中用new初始化它,但这感觉很笨拙。有没有关于如何解决这个问题的建议(没有双关语)? 编辑:我使用vector类来表示我打算绕任意轴旋转的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];
    }

我采纳了@n.m.和@Chris Dodd的建议,从我的向量头中删除了Matrix3 include,并将其放入向量实现文件中,如下所示:

    //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"
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;
   }
};

由于您处理的是向量和矩阵,因此可以使用维度模板(可能还有元素类型)定义单个矩阵类——然后向量类(取决于向量的类型)将是一个维度之一为1的矩阵。如果你这样做,你只会得到一个类,一组代码和所有你想要的功能。您可以避免任何类间依赖,因为您只有一个类

类本身看起来像这样:

    //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"
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;
   }
};
模板
类矩阵{
te[m*n];
公众:
T*运算符[](无符号i){返回e+i;}
T*常量运算符[](无符号i)常量{返回e+i;}
/*对-、*、/--相同图案重复此操作*/
矩阵和运算符+=(矩阵常数和a){
对于(无符号i=0;i
然后,您应该定义任何函数,这些函数在类外不采用大小相等的矩阵(这就是为什么我们使用[]运算符)。请注意,*和/运算符作用于所有元素,不计算通常的矩阵乘法或矩阵除法。相反,您需要一个反转函数和一个乘法函数

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&);
模板
矩阵常数乘法(矩阵常数a、矩阵常数b);
样板
矩阵常数倒置(矩阵常数&);
样板
矩阵常数转置(矩阵常数&);
请注意,如果您有一种方法来反转一个通用的非方矩阵(我不知道其中的任何一种),那么上面的模板将只适用于一个方矩阵。作为练习,填写我留给您的函数的代码

要获得3矢量和3x3矩阵,您可以按如下方式键入它们:

typedef matrix<3,1,float> vector3f;
typedef matrix<3,3,float> matrix3x3f;
typedef矩阵向量3f;
类型定义矩阵矩阵x3f;
记住添加比较运算符以及您需要的任何其他内容

如果愿意,还可以添加矩阵标量、标量矩阵运算符和函数(以简化,例如,向矩阵中的所有元素添加标量)


如果希望更好地控制[]运算符中的元素,可以使用vectors作为基类,然后将矩阵定义为向量向量。这将给您带来相同的优势,但可能更适合您的思维方式(许多人认为向量和矩阵是不同的类型)。

向量类不应该依赖于矩阵类。为什么矢量旋转依赖于矩阵?@Egg检查我的编辑。我使用矩阵将点转换为新的坐标系,使用旋转矩阵进行旋转,然后将点恢复到原始坐标系。我在想也许旋转不应该出现在vector类上,但我不知道放在哪里,这将是对它们的常见操作。
向量
不包含
矩阵
,因此
向量
声明只需要向前声明
矩阵
(如果有)。一个
矩阵
包含三个
向量
,因此存在一个完整的依赖关系。将代码“按您的意愿”删除
#包括
向量3.h
中的
行。现在一切都会好起来的。如果不是的话,你还有一些不应该有的奇怪的依赖性,你没有表现出你的问题是循环包含。向量3.h包括矩阵3.h,矩阵3.h包括向量3.h。这是行不通的。从Vector3.h中删除
#包括“Matrix3.h”
,问题就会消失。