运算符+ =可以调用自身,但是“* this”与“rhs”交换?

时间:2014-01-15 23:22:53

标签: c++ operator-overloading

编辑:我想在响应之前添加这个...这是一个类的赋值的一部分,所以我必须坚持使用底层数组,我必须坚持重载运算符,没有那个花哨的模板jazzy东西(我不会理解)。

EDIT2:我基本上想接听电话“A + B”,但在我的功能中将其反转,以便它是“B + A”

我的目标是最小化新内存分配的数量,因此如果可能的话,我想避免在以下方法中调用复制构造函数('if'情况):

Poly& Poly::operator+=(const Poly& rhs) {
    // actual addition of rhs to *this
    if (maxExponent < rhs.maxExponent) {
        Poly temp(rhs);

        for (int i = 0; i <= maxExponent; i++) {
            temp.polynomial[i] += polynomial[i];
        }

        *this = temp;
        //return *this;
    }
    else {
        for (int i = 0; i <= rhs.maxExponent; i++) {
            polynomial[i] += rhs.polynomial[i];
        }
    }

    return *this;
}

我以为我会成为一个聪明人并尝试这种偷偷摸摸的策略......但是我无法获得正确的类型转换以使其正常工作(如果可能的话):

Poly& Poly::operator+=(const Poly& rhs) {
    // actual addition of rhs to *this
    if (maxExponent < rhs.maxExponent) {
        return (rhs + *this);
    }
    else {
        for (int i = 0; i <= rhs.maxExponent; i++) {
            polynomial[i] += rhs.polynomial[i];
        }
    }

    return *this;
}

我的思维过程基本上是通过调用自身但是切换参数的顺序我可以直接使用rhs,因为它不再是const而且我甚至不需要调整新数组的大小。这是我的操作员+作为参考,因为他们一起工作:

inline Poly operator+(Poly lhs, const Poly& rhs)
{
    lhs += rhs;
    return lhs;
}

我正在尝试做什么?

2 个答案:

答案 0 :(得分:1)

  

我的目标是最小化新内存分配的数量,因此我希望在可能的情况下避免对以下方法中的复制构造函数(if情况)的调用

然后只是不要创建一个临时Poly对象。在if(false)案例中,您正在直接修改lhs.polynomial。在if(true)案例中也做同样的事情。 +=运算符的整个目的是使用添加的结果修改lhs,而+运算符的目的是返回添加结果的副本而不修改{{ 1}}。

所以尝试这样的事情:

lhs

更新:假设您希望在Poly& Poly::operator+=(const Poly& rhs) { int num = (maxExponent < rhs.maxExponent) ? maxExponent : rhs.maxExponent; for (int i = 0; i <= num; i++) { polynomial[i] += rhs.polynomial[i]; } //... return *this; } inline Poly operator+(Poly lhs, const Poly& rhs) { lhs += rhs; return temp; } 时增长lhs.polynomial,但在lhs.maxExponent < rhs.maxExponent时不缩小lhs.polynomial,那么请尝试更多类似的内容:

rhs.maxExponent < lhs.maxExponent

答案 1 :(得分:0)

您在寻找:

template<typename T, typename U>
friend Poly operator+(T&& lhs, U&& rhs)
{
    if (lhs.maxExponent < rhs.maxExponent)
        return Poly(std::forward<U&&>(rhs)) += lhs;
    return Poly(std::forward<T&&>(lhs)) += rhs;
}

(由于是friend,它只能通过参数依赖查找找到,并且只有当参数是Poly时才会找到。你可以用一些enable_if来增加它。 )

(你可以在没有模板的情况下做到这一点......但最终你有四个版本:lhsrhs可以是const Poly&Poly&&四种组合。对于其中一些组合,std::forward没有任何好处,但也没有任何伤害。)

直接回答您的问题 - 不,交换lhs的{​​{1}}和rhs是一个不好的主意。 lhs += rhs应该修改左侧的对象并保持右侧不变。这意味着您无法从+=窃取资源(除非它当然是右值参考。)

一个案例rhs可以从operator+=窃取资源,当它是左值参考时,则:

rhs