为什么当我使用重载赋值运算符时会出现错误,而我没有使用编译器提供的运算符?

Why do I get errors when I use the overloaded assignment operator, but I don't get using the compiler-supplied one?

提问人:H-005 提问时间:8/30/2020 最后编辑:songyuanyaoH-005 更新时间:8/30/2020 访问量:54

问:

我尽力只放最重要的部分:

header.h

#include <cstdint>
#include <string>
#include <vector>
#include "byte.h" /// doesn't matter what's in here
#pragma once

using int64 = int64_t;
using int32 = int32_t;

/// FORWARD-DECLARATIONS
class BigInt;

/// *** CLASS BIGINT ***

class BigInt
{
    std::vector<byte> vec;
    bool neg; /// true if negative

public:
    /// CONSTRUCTORS
    BigInt ();
    BigInt (const int64);

    /// OPERATORS
    /// ASSIGNMENT
    void operator = (const BigInt&);

    /// ARITHMETIC
    BigInt operator + (const BigInt&);
    BigInt operator - (const BigInt&);
};

/// DEFINITIONS
/// CONSTRUCTORS
BigInt::BigInt () : vec(1), neg(0) {}
BigInt::BigInt (const int64 x) : vec(x), neg(0) {}

/// OPERATORS
/// ASSIGNMENT
void BigInt::operator = (const BigInt &p)
{
    (*this).vec = p.vec;
    (*this).neg = p.neg;
}

/// ARITHMETIC
BigInt BigInt::operator + (const BigInt &p)
{
    BigInt a = *this;
    BigInt b = p;
    BigInt res;

    if (a.neg ^ b.neg)
    {
        if (a.neg)
            std::swap(a, b);
        b.neg = 0;
        /*return*/ res = a.BigInt::operator - (b); /// I get an error if I don't comment this out
        return res;
    }

    return res;
}

BigInt BigInt::operator - (const BigInt &p)
{
    BigInt a = *this;
    BigInt b = p;
    BigInt res;

    return res;
}

当我尝试返回时,我收到错误,但当我像这样返回它时却没有:。但这只有在我重载运算符时才会发生,编译器提供的运算符不会发生这种情况。BigInt BigInt::operator + (const BigInt &p)return res = a.BigInt::operator - (b);res = a.BigInt::operator - (b); return res;=

错误:从类型“void”的返回值到函数返回类型“BigInt”的转换不行 return res = a.BigInt::operator - (b);

C++ return-type 赋值运算符

评论


答:

3赞 songyuanyao 8/30/2020 #1

正如错误消息所说,您的返回值无法返回,应该返回 .operator=voidreturn res = a.BigInt::operator - (b);operator +BigInt

您应该声明为返回(就像编译器生成的一样)。operator=BigInt&

BigInt& BigInt::operator = (const BigInt &p)
{
    (*this).vec = p.vec;
    (*this).neg = p.neg;
    return *this;
}

评论

0赞 H-005 8/30/2020
是的,我认为修改(*这个)就足够了。谢谢!
1赞 rajdakin 8/30/2020
顺便说一句,您还可以在标头中声明赋值运算符,并避免在文件中定义它,或者您可以根本不包含此运算符(请参阅三五零规则)。截至目前,您无法通过复制进行构造,并且没有移动操作。另请参阅C++核心指南中的C.20BigInt &operator = (const BigInt &) noexcept = default;
2赞 paxdiablo 8/30/2020 #2
void BigInt::operator = (const BigInt &p)

我认为这是不对的(回报)。赋值的结果应该是赋值,这允许您执行以下操作:void

a = b = 7

或者,更重要的是,在这种情况下:

return res = ...

可能应该返回您输入值的变量,例如:operator=BigInt&

BigInt &BigInt::operator=(const BigInt &p) {
    this->vec = p.vec;
    this->neg = p.neg;
    return *this;
}

评论

0赞 H-005 8/30/2020
哦,我以为例如会存储在指针上,所以当我修改(*this)时,它会修改左操作数。但它就像你说的一样,谢谢!resthis
2赞 paxdiablo 8/30/2020
@H-005:它确实会修改,但这只是所需的两个效果之一,另一个是返回赋值表达式的值。换句话说,将修改(即)为七。但是,如果表达式的结果是空的“类型”,则不能这样做。*thisb = 7*thisbb = 7a = b = 7