0

我有两个类,一个顶点和一个向量,我正在尝试使用运算符来简化生活。如果您将检查下面介绍的向量和顶点类,我正在尝试在顶点和向量中实现运算符。

比如VertexA+VertexB = VectorC //没用那么多...

VertexA-VertexB = VectorC //可以很频繁地使用

VertexA+VectorB = VertexC //可以用得很频繁

VertexA-VectorB = VertexC //可以很频繁地使用

VectorA+VectorB = VectorC //使用

VectorA-VectorB = VectorC //使用

VectorA+VertexB = VertexC //使用

VectorA-VertexB = VertexC //使用

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

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

#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;
    }
};
4

2 回答 2

0

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

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

在你的情况下,如果你只实现Vertex& operator+=(const Vector& other), Vertex& operator-=(const Vector& other), Vector& operator+=(const Vector& other), and 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。

我的助手实现使用第一个参数的类型作为运算符的返回类型。这就是为什么您的其他情况不包括在内的原因。但是这种情况意味着从向量到顶点的转换或/和反之亦然。如果您修改实现以执行此操作,则可以涵盖所有情况。

于 2013-07-03T01:14:26.640 回答
0

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

于 2013-07-03T02:13:51.287 回答