【问题标题】:Operator overloading for Int type classInt 类型类的运算符重载
【发布时间】:2015-11-19 03:48:30
【问题描述】:

我正在编写一个简单的 Int 类并使用运算符重载来使对象的行为方式与“int”类似。我已将整个程序分成 3 个文件,1)头文件:包含类声明 2)所有运算符重载函数的定义 3)包含 main 的测试文件 这三个在这里按顺序提到

#include <iostream>
using namespace std;

class Int
{
private:
    int i;
public:
    Int(): i(0) { }
    Int(int in) : i(in) { }
    void show() const
    {
        cout<<"value: "<<i<<endl;
    }
    Int operator +(const Int&) const;
    Int operator -(const Int&) const;
    Int operator *(const Int&) const;
    Int operator /(const Int&) const;
    //Int add(const Int&) const; 
};

函数定义

#include <iostream>
#include <climits>
#include <cassert>
#include "int.h"
using namespace std;
typedef unsigned long long ull;

Int Int::operator +(const Int &i1) const
{

    ull result;
    result = i+ i1.i;
    //cout<< result<<'\n';
    if (result>INT_MAX)
    {
        cout<<"Out of int range.\n";
        //assert(0);
    }
    else
        return Int(int(result));
}

Int Int::operator -(const Int &i1) const
{
    //typedef unsigned long long ull;
    ull result;
    result = i - i1.i;
    //cout<< result<<'\n';
    if (result < INT_MIN)
    {
        cout<<"Out of int range.\n";
        //assert(0);
    }
    else
        return Int(int(result));
}

Int Int::operator *(const Int &i1) const
{
    //typedef unsigned long long ull;
    ull result;
    result = i* i1.i;
    //cout<< result<<'\n';
    if (result >INT_MAX)
    {
        cout<<"Out of int range.\n";
        //assert(0);
    }
    else
        return Int(int(result));
}

Int Int::operator /(const Int &i1) const
{
    //typedef unsigned long long ull;
    ull result;
    result = i/ i1.i;
    //cout<< result<<'\n';
    if (result < INT_MIN)
    {
        cout<<"Out of int range.\n";
        //assert(0);
    }
    else
        return Int(int(result));
}

并用 main 测试程序:

#include <iostream>
#include "int.h"

int main(int argc, char const *argv[])
{
    Int i1;
    Int i2(4);Int i3(2);
    i1 = i2 + i3;
    i1.show();
    i1 = i2 - i3;
    i1.show();
    i1 = i2 * i3;
    i1.show();
    i1 = i2 / i3;
    i1.show();
    return 0;
}

预期输出是:

Value : 6,
Value : 2,
value : 8
Value : 2.

但是我得到这样的输出:

value: 6
Out of int range.
value: 6
value: 8
Out of int range.
value: 8

我尝试了很多错误但无法找到的地方。 任何线索都会有很大帮助。

【问题讨论】:

  • 顺便说一句,如果您希望您的课程尽可能像int,只需使用一些其他方法,不要开始制作 + - 等,而是制作(非显式) int 的强制转换运算符(除了您已经存在的另一个方向的构造函数)
  • @vik14dec 乍一看,成员操作符 (Int::operator + (const Int&amp;)) 比独立版本 (friend Int operator + (const Int&amp;, const Int&amp;)) 更容易实现 - 我强烈建议尽可能选择独立版本。 ..
  • 你应该在 if 分支中添加一个 throw 或 return 顺便说一句
  • Daniel Jour,我为此使用了“assert(0)”。只是为了检查输出,我对此进行了评论并在此处粘贴了代码。

标签: c++ class int operator-overloading


【解决方案1】:

问题是无符号值与有符号值的比较:

if (result < INT_MIN)

更根本的是,当你想表现得像一个签名的int 时,为什么你希望结果是unsigned long long

我理解您为什么要使用 long long 进行范围检查 int 操作(尽管这样做并不完全可移植),但选择 unsigned 似乎只是一个错误。

【讨论】:

  • 这个!只需使用int 而不是ull,你就不需要所有的转换
【解决方案2】:

您的operator- 导致第一次超出范围。在该运算符中,您有

    ull result;

然后

if (result < INT_MIN)

INT_MIN 是实现定义的负值,但是result 是无符号的并且是unsigned long long 类型。 通常的算术转换 (C++11 §5[expr]/9) 规定在这种情况下INT_MIN 被转换为unsigned long long。这是一个“模”转换,所以它变成一个相当大的正整数,在任何情况下都比你的例子中结果的值 2 大得多。

【讨论】:

    【解决方案3】:

    在您打印cout&lt;&lt;"Out of int range.\n"; 的情况下,您不会返回任何值。

    您还应该使用longlong long 作为类型。 int 可能不是 32 位的。 并且使用unsigned 类型会产生错误的结果(想想-1 * -1)

    你需要的是这样的:

    #include <iostream>
    using namespace std;
    
    class Int
    {
    private:
        long i;
    public:
        Int() : i(0) { }
        Int(long in) : i(in) { }
        Int(const Int& other) :i(other.i) {}
    
        void show() const
        {
            cout << "value: " << i << endl;
        }
    
    
        Int& operator+=(const Int& other) 
        {
            long long result = i;
            result += other.i;
            if (result >= LONG_MIN && result <= LONG_MAX)
            {
                i = result;
            }
            else
            {
                cout << "Out of int range." << endl;
            }
            return *this;
        }
    
        Int operator-=(const Int& other) {
            long long result = i;
            result -= other.i;
            if (result >= LONG_MIN && result <= LONG_MAX)
            {
                i = result;
            }
            else
            {
                cout << "Out of int range." << endl;
            }
            return *this;
        }
    
        Int operator*=(const Int& other) 
        {
            long long result = i;
            result *= other.i;
            if (result >= LONG_MIN && result <= LONG_MAX)
            {
                i = result;
            }
            else
            {
                cout << "Out of int range." << endl;
            }
            return *this;
        }
    
        Int operator/=(const Int& other) 
        {
            long long result = i;
            result /= other.i;
            if (result >= LONG_MIN && result <= LONG_MAX)
            {
                i = result;
            }
            else
            {
                cout << "Out of int range." << endl;
            }
            return *this;
        }
    
        Int operator+(const Int& other) const
        {
            return Int(*this) += other;
        };
    
        Int operator-(const Int& other) const
        {
            return Int(*this) -= other;
        };
    
        Int operator*(const Int& other) const
        {
            return Int(*this) *= other;
        };
    
        Int operator/(const Int& other) const
        {
            return Int(*this) /= other;
        };
    };
    

    【讨论】:

    • 感谢这些速记运算符的代码。问题出在我的“无符号”变量上。修复它,现在很完美。
    • 不仅如此。试试这个(Int(INT_MAX) + Int(INT_MAX) + Int(INT_MAX)).show(); 你需要决定在“越界”情况下返回什么。
    【解决方案4】:

    我发现您的代码有两个问题。

    首先,将无符号值(结果)与有符号常量 (INT_MIN) 进行比较。

    其次,如果你在越界检查中注释掉'assert'语句,你仍然必须从函数中返回一个值。一些编译器可能会用类似这样的东西警告你:“控制到达非空函数的结尾。”这现在可能不会显示,但是当您开始捕获错误时,您的程序很可能会崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      • 2015-01-29
      • 2015-12-24
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      相关资源
      最近更新 更多