2015-08-25 2 views
1

Я пишу простой класс Int и использую перегрузку оператора, чтобы позволить объектам вести себя так же, как и «int». Я сломал всю мою программу в 3-х файлов, 1) Заголовок файла: содержит объявление класса 2) Определение всех перегружена функций 3) Тестовый файл, содержащий основной Эти три упомянуты здесь в том же порядкеПерегрузка оператора для класса типа Int

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

и тестовая программа с основной:

#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 

Я пробовал много, где я неправильно, но не смог найти. Любое руководство будет отличной помощью.

+0

Кстати, если вы хотите, чтобы ваш класс был как можно больше «int», просто с некоторыми дополнительными методами, не начинайте делать + - и т. Д., Но создавайте (неявный) оператор литья для 'int '(в дополнение к вашему уже существующему конструктору для другого направления) – deviantfan

+0

@ vik14dec С первого взгляда может показаться, что операторы-члены (' Int :: operator + (const Int &) ') проще реализовать, чем автономная версия (' friend Int operator + (const Int &, const Int &) ') - Я настоятельно рекомендую всегда предпочитать автономные версии, когда это возможно .... – PiotrNycz

+0

Вы должны добавить бросок или возврат внутри этих' if' ветвей btw –

ответ

3

Проблема является сравнением беззнакового значения с подписанным значением:

if (result < INT_MIN) 

Более фундаментально, почему вы хотите, чтобы результат unsigned long long когда вы хотите, чтобы действовать как знаковый int?

Я понимаю, почему вы хотите использовать long long для проверки диапазона int операций (хотя делать это не совсем портативный), но выбор unsigned, кажется, просто ошибка.

+0

Это! Просто используйте 'int' вместо' ull', и вам не нужно все это кастинг – romeric

+0

Да, вы правы JSF. Спасибо. – vvs14

1

Ваш operator- выдает первый выход за пределы диапазона. В этом оператора, у вас есть

ull result; 

и затем

if (result < INT_MIN) 

INT_MIN является реализация определенных отрицательное значение, однако result беззнаковым и типа unsigned long long. Обычные арифметические преобразования (C++ 11 §5 [expr]/9) диктуют, что в этом случае INT_MIN преобразуется в unsigned long long. Это преобразование «по модулю», поэтому оно становится довольно большим положительным целым числом, в любом случае намного большим, чем значение 2 результата вашего примера.

0

В случае, когда вы печатаете cout<<"Out of int range.\n";, вы не возвращаете никаких значений.

Также вы должны использовать 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; 
    }; 
}; 
+0

Спасибо за код коротких операторов. Проблема заключается в моей переменной «unsigned». Исправлена ​​ошибка, и теперь она прекрасна. – vvs14

+0

Не только. Попробуйте использовать один из них (Int (INT_MAX) + Int (INT_MAX) + Int (INT_MAX)). Show(); ' Вам нужно решить, что возвращать в случае« вне пределов ». –

0

Я вижу две проблемы с кодом.

Сначала вы сравниваете значение без знака (результат) с подписанной константой (INT_MIN).

Во-вторых, если вы закомментируете утверждение 'assert' в проверке вне пределов, вы все равно должны вернуть значение из функции. Некоторые компиляторы могут предупредить вас примерно так: «control достигает конца не-void функции». Это может не отображаться прямо сейчас, но когда вы начинаете ошибки захвата, ваша программа, скорее всего, сбой.

Смежные вопросы