内在循环依赖C++顶点和向量

Inherent Circular Dependency C++ Vertex and Vectors

本文关键字:顶点 向量 C++ 依赖 循环      更新时间:2023-10-16

我有两个类,一个顶点和一个向量,我正在尝试使用运算符来简化生活。如果您要研究下面给出的向量和顶点类,我将尝试在顶点和向量中实现操作符。

例如VertexA+VertexB=VectorC//用得不多。。。

VertexAVertexB=VectorC//可能经常使用

VertexA+VectorB=VertexC//可以非常频繁地使用

VertexA VectorB=VertexC//可以非常频繁地使用

VectorA+VectorB=VectorC//使用的

VectorA VectorB=VectorC//使用的

VectorA+VertexB=VertexC//使用

VectorA VertexB=使用的

如果您注意到存在循环依赖关系。为了使一个类的运算符通过值(而不是通过引用或指针)返回

我知道有一种方法,把顶点表示为向量。然而,我想知道是否有不同的解决方案,因为为了清晰起见,我喜欢这两个不同的类。

#ifndef decimal
    #ifdef PRECISION
        #define decimal double
    #else
        #define decimal float
    #endif
#endif
class Vector;
class Vertex{
public:
    decimal x,y;
    const Vertex operator+(const Vector &other);
    const Vertex operator-(const Vector &other);
    const Vector operator+(const Vertex &other);
    const Vector operator-(const Vertex &other);
};
class Vector{
public:
    decimal x,y;
    const Vector operator+(const Vector &other) const {
        Vector result;
        result.x=this->x+other.x;
        result.y=this->y+other.y;
        return result;
    }
    const Vector operator-(const Vector &other) const {
        Vector result;
        result.x=this->x-other.x;
        result.y=this->y-other.y;
        return result;
    }
    const Vertex operator+(const Vertex &other) const {
        Vertex result;
        result.x=this->x+other.x;
        result.y=this->y+other.y;
        return result;
    }
    const Vertex operator-(const Vertex &other) const {
        Vertex result;
        result.x=this->x-other.x;
        result.y=this->y-other.y;
        return result;
    }
    decimal dot(const Vector &other) const{
        return this->x*other.x+this->y*other.y;
    }
    const decimal cross(const Vector &other) const{
        return this->x*other.y-this->y*other.x;
    }
};

为了使这种类型的代码(算术数据类型)易于编写,通常我使用一组名为"运算符重载助手"的模板,如Boost运算符标头。检查我的实现。

这种方法的优点是运算符的实现是一致的(operator+=实现与operator+实现一致,等等)。

在您的情况下,如果您只实现Vertex& operator+=(const Vector& other)Vertex& operator-=(const Vector& other)Vector& operator+=(const Vector& other)Vector& operator-=(const Vector& other);你负责第3到第5个案子。怎样

检查此代码:

//Forward declaration needed:
class Vector;
struct Vertex : public dl32AdditionHelper<Vertex , Vector , true>,      //The last parameter is used to enable operator+ simmetry. That is, this covers cases 3 and 7.
                public dl32SubstractionHelper<Vertex , Vector , false>, //This covers case 4 (Simmetry si not enabled, see note bellow).
{
    float x , y;
    //For Vertex + Vector = Vertex
    Vertex& operator+=(const Vector& other)
    {
        x += other.x;
        y += other.y;
        return *this;
    }
    //For Vertex - Vector = Vertex
    Vertex& operator-=(const Vector& other)
    {
        x += other.x;
        y += other.y;
        return *this;
    }
};
struct Vector : public dl32AdditionHelper<Vector>,     //This covers case 5.
                public dl32SubstractionHelper<Vector>, //This covers case 6.
{
    float x , y;
    //For Vector + Vector = Vector
    Vector& operator+=(const Vector& other)
    {
        x += other.x;
        y += other.y;
        return *this;
    }
    //For Vector - Vector = Vector
    Vector& operator-=(const Vector& other)
    {
        x += other.x;
        y += other.y;
        return *this;
    }
};

仅此而已。

对称注意:对称属性意味着对于给定的运算符#,运算a#b等于b#a。算术助手使用此功能来提供对称运算符。例如,矩阵代数:m1+m2=m2+m1,因此operator+(const matrix_type_2& m1 , const matrix_type_1& m2)实现为m2 + m1(对operator+(const matrix_type_1& m1 , const matrix_type_2& m2)的调用)。正如你所看到的,对称性不适用于情况8。

我的助手实现使用第一个参数的类型作为运算符的返回类型。这就是为什么你的其他案件不包括在内的原因。但这种情况意味着从矢量到顶点或/或反之亦然。如果您修改实现以做到这一点,那么您的所有案例都可以涵盖在内。

Forward声明实际上解决了我的问题。我遇到的编译问题是因为我的函数签名没有以一种不明显的方式正确匹配。