Int 类型的运算符重载 class
Operator overloading for Int type class
我正在编写一个简单的 Int class 并使用运算符重载来使对象的行为方式与 "int" 类似。我已将整个程序分成 3 个文件,1) 头文件:包含 Class 声明 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
我尝试了很多错误的地方,但找不到。
任何线索都会有很大帮助。
问题是无符号值与有符号值的比较:
if (result < INT_MIN)
更根本的是,当你想表现得像一个带符号的 int
时,为什么你希望结果是 unsigned long long
?
我明白你为什么要使用 long long
来进行范围检查 int
操作(尽管这样做并不完全可移植)但是 unsigned
的选择似乎只是一个错误。
您的 operator-
导致第一次超出范围。在该运算符中,您有
ull result;
然后
if (result < INT_MIN)
INT_MIN
是实现定义的负值,但是 result
是无符号的并且类型为 unsigned long long
。 通常的算术转换 (C++11 §5[expr]/9) 规定在这种情况下 INT_MIN
被转换为 unsigned long long
。这是一个 "modulo" 转换,因此它变成了一个相当大的正整数,在任何情况下都比您的示例结果的值 2
大得多。
在您打印 cout<<"Out of int range.\n";
的情况下,您没有 return 任何值。
您还应该使用 long
和 long 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_MIN) 进行比较。
其次,如果你在越界检查中注释掉'assert'语句,你仍然必须return一个来自函数的值。一些编译器可能会用这样的警告你:"control reaches end of non-void function."这可能不会立即显示,但当你开始捕获错误时,你的程序很可能会崩溃。
我正在编写一个简单的 Int class 并使用运算符重载来使对象的行为方式与 "int" 类似。我已将整个程序分成 3 个文件,1) 头文件:包含 Class 声明 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
我尝试了很多错误的地方,但找不到。 任何线索都会有很大帮助。
问题是无符号值与有符号值的比较:
if (result < INT_MIN)
更根本的是,当你想表现得像一个带符号的 int
时,为什么你希望结果是 unsigned long long
?
我明白你为什么要使用 long long
来进行范围检查 int
操作(尽管这样做并不完全可移植)但是 unsigned
的选择似乎只是一个错误。
您的 operator-
导致第一次超出范围。在该运算符中,您有
ull result;
然后
if (result < INT_MIN)
INT_MIN
是实现定义的负值,但是 result
是无符号的并且类型为 unsigned long long
。 通常的算术转换 (C++11 §5[expr]/9) 规定在这种情况下 INT_MIN
被转换为 unsigned long long
。这是一个 "modulo" 转换,因此它变成了一个相当大的正整数,在任何情况下都比您的示例结果的值 2
大得多。
在您打印 cout<<"Out of int range.\n";
的情况下,您没有 return 任何值。
您还应该使用 long
和 long 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_MIN) 进行比较。
其次,如果你在越界检查中注释掉'assert'语句,你仍然必须return一个来自函数的值。一些编译器可能会用这样的警告你:"control reaches end of non-void function."这可能不会立即显示,但当你开始捕获错误时,你的程序很可能会崩溃。