Почему этот перегруженный оператор выдает неправильный вывод? - PullRequest
0 голосов
/ 29 апреля 2020

Выходные данные для сложения и вычитания целых дают мне правильное решение, но при попытке добавить строку в int должно привести к ошибке, но это не так. Не знаю, где я ошибся.

ERROR + 3 is ERROR
ERROR - 4 is ERROR
ERROR + hello is ERROR
ERROR - world is ERROR
3 + ERROR is ERROR
3 - ERROR is ERROR
3 + 4 is 7
3 - 4 is -1
**3 + hello is 7  
3 - world is -1
4 + ERROR is 7** 
4 + 3 is 7
4 - 3 is 1
**4 + hello is 7
4 - world is 1
**hello + ERROR is 7
hello - 3 is 1
hello + 4 is 7**
hello + world is helloworld
**hello - world is 1**
world + ERROR is helloworld
world - ERROR is 1
world + 3 is helloworld
world - 3 is 1
world + 4 is helloworld
world - 4 is 1
world + hello is worldhello
world - hello is 1

Ниже приведен заголовочный файл с геттерами для возврата in или строки.

#ifndef VALUE_H
#define VALUE_H

#include <iostream>
#include <string>
using namespace std;

enum ValType
{
    VINT,
    VSTR,
    VERR
};

class Value
{
    ValType T;
    int I;
    string S;

public:
    Value() : T(VERR), I(0) {}
    Value(int vi) : T(VINT), I(vi) {}
    Value(string vs) : T(VSTR), I(0), S(vs) {}

    ValType GetType() const { return T; }
    bool IsErr() const { return T == VERR; }
    bool IsInt() const { return T == VINT; }
    bool IsStr() const { return T == VSTR; }

    int GetInt() const
    {
        if (IsInt())
            return I;
        throw "RUNTIME ERROR: Value not an integer";
    }
    string GetStr() const
    {
        if (IsStr())
            return S;
        throw "RUNTIME ERROR: Value not a string";
    }

    // add op to this
    Value operator+(const Value &op) const
    {
        try
        {
            if (IsInt() && op.IsInt()) // integer addition
                return GetInt() + op.GetInt();
            if (IsStr() && op.IsStr()) // string addition
                return GetStr() + op.GetStr();
        }
        catch (std::string &e)
        {
            cout << "RUNTIME ERROR " << e << endl;
        }

        //throw "RUNTIME ERROR...";
    }

    // subtract op from this
    Value operator-(const Value &op) const
    {
        try
        {
            if (IsInt() && op.IsInt()) // integer addition
                return GetInt() - op.GetInt();
        }
        catch (std::string &e)
        {
            cout << "RUNTIME ERROR " << e << endl;
        }
        //throw "RUNTIME ERROR...";
    }

    // multiply this by op
    Value operator*(const Value &op) const;

    // divide this by op
    Value operator/(const Value &op) const;

    friend ostream &operator<<(ostream &out, const Value &op)
    {
        if (op.IsInt())
            out << op.I;
        else if (op.IsStr())
            out << op.S;
        else
            out << "ERROR";
        return out;
    }
};

#endif

Ниже приведен основной драйвер, принимающий целые и строки в качестве значений, проходя по ним

#include <iostream>
#include <string>
#include <vector>
using namespace std;
#include "val.h"

void doOp(const Value &a, const Value &b)
{
    cout << a << " + " << b << " is " << flush << a + b << endl;
    cout << a << " - " << b << " is " << flush << a - b << endl;
}



int main()
{

    Value a;
    Value b(3);
    Value c(4);
    Value d("hello");
    Value e("world");

    vector<Value> vals({a, b, c, d, e});

    cout << "a=" << a << endl;
    cout << "b=" << b << endl;
    cout << "c=" << c << endl;
    cout << "d=" << d << endl;
    cout << "e=" << e << endl;

    for (int i = 0; i < 5; i++)
        for (int j = 0; j < 5; j++)
            if (i != j)
                doOp(vals[i], vals[j]);

    return 0;
}

Ответы [ 3 ]

0 голосов
/ 29 апреля 2020

Ваш код ничего не возвращает за недопустимую операцию. Недопустимое сложение или вычитание должно возвращать пустое значение Value()

Value operator+(const Value &op) const
{
    try
    {
        if (IsInt() && op.IsInt()) // integer addition
            return GetInt() + op.GetInt();
        if (IsStr() && op.IsStr()) // string addition
            return GetStr() + op.GetStr();
    }
    catch (std::string &e)
    {
        cout << "RUNTIME ERROR " << e << endl;
    }
    return Value();
    //throw "RUNTIME ERROR...";
}

// subtract op from this
Value operator-(const Value &op) const
{
    try
    {
        if (IsInt() && op.IsInt()) // integer addition
            return GetInt() - op.GetInt();
    }
    catch (std::string &e)
    {
        cout << "RUNTIME ERROR " << e << endl;
    }
    //throw "RUNTIME ERROR...";
    return Value();
}
0 голосов
/ 29 апреля 2020

Возвращаемые значения ваших operator+ и operator- являются неопределенными , когда два сравниваемых объекта Value не относятся к одному и тому же типу. В случае несоответствия вам нужно вернуть пустой Value, так как ваш конструктор по умолчанию инициализирует член ValType T в VERR:

Value operator+(const Value &op) const
{
    if (IsInt() && op.IsInt()) // integer addition
        return GetInt() + op.GetInt();
    if (IsStr() && op.IsStr()) // string addition
        return GetStr() + op.GetStr();
    return Value();
}

// subtract op from this
Value operator-(const Value &op) const
{
    if (IsInt() && op.IsInt()) // integer subtraction
        return GetInt() - op.GetInt();

    // in comments, you said you want "hello - world" to be "hello"
    if (IsStr() && op.IsStr()) // string subtraction
        return GetStr();

    return Value();
}
0 голосов
/ 29 апреля 2020

Для начала операторы имеют неопределенное поведение, потому что они ничего не возвращают в случае, когда типы активных элементов данных не совпадают. Блок try-catch является избыточным в теле операторов, поскольку не генерируется ни одно исключение.

Value operator+(const Value &op) const
{
    try
    {
        if (IsInt() && op.IsInt()) // integer addition
            return GetInt() + op.GetInt();
        if (IsStr() && op.IsStr()) // string addition
            return GetStr() + op.GetStr();
    }
    catch (std::string &e)
    {
        cout << "RUNTIME ERROR " << e << endl;
    }

    //throw "RUNTIME ERROR...";
}
...