Объяснение перегрузки оператора - PullRequest
0 голосов
/ 14 мая 2018

Я пытаюсь понять вывод короткой программы, где используется перегрузка оператора.

Выход 137, где (2+v).print() вывод 13 и 7 от v.print();

#include <iostream>
using namespace std;

class V
{
    int x;
public:
    V(int a = 7, int b = 3) { x = a + b; }
    void print() { cout << x; }
    V operator+(int n)
    {
        return x++ + ++n;
    }
};

V operator+(int lop, V rop)
{
    return rop + lop;
}

int main()
{
    V v(1, 6);
    (2 + v).print();
    v.print();
    return 0;
}

Я понимаю базовую концепцию перегрузки операторов и получаю, что V rop является просто копией V v(1,6), и это не меняет вывод v.print();, где x остается 7, но я не понимаю, почему выводит 13, я всегда получаю 10.

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Проблема заключается в том, что при попытке вернуть объект типа 'V' из этого оператора:

V operator+(int n)
{
    return x++ + ++n;
}

То, что вы пытаетесь вернуть здесь в виде 'int', поэтому его следует привести кобъект типа 'V', способ, которым это делается (приведение типа примитива к пользовательскому классу), использует конструкторы. Единственный конструктор, который у вас есть, с двумя необязательными параметрами, который создает проблему, которую он пытаетсясделать объект только из одного параметра, поэтому он отправляется как a = 10, b = 3 (значение по умолчанию), а затем выводится 13.

Я рекомендую использовать несколько конструкторов для решения проблемы, если вы нея не хочу изменять членов класса.

class V
{
    int x;
public:
    V() { x = 10; }
    V(int a) { x = a; }
    V(int a, int b) { x = a + b; }
    void print() { cout << x; }
    V operator+(int n)
    {
        return x++ + ++n;
    }
};

Таким образом, вы можете вызвать конструктор по умолчанию, который устанавливает x в 10, как вы делали ранее, другой конструктор с 1 параметром для приведения из int в'V', и ваш обычный конструктор, который принимает a и b.

0 голосов
/ 15 мая 2018

В вашем code при достижении return (x++ + ++n); компилятора создайте объект V, чтобы ваш конструктор снова вызывался. тогда эти назначения будут происходить a=10 и b=3. Таким образом, вы должны сохранить a и b значения в другом members.

Попробуйте это:

#include <iostream>
using namespace std;

class V {
    int x;
    int a;
    int b;

public:
    V(int a=7, int b=3) { x = a + b; this->a = a; this->b = b; }
    void print() { cout << x - this->b; }
    V operator+(int n) {
    return (x++ + ++n);
    }
};

V operator+(int lop, V rop) {
    return rop + lop;
}
int main()
{
    V v(1,6);
    (2 + v).print();
    v.print();

    return 0;
}

Ваш (2 + v).print(); вывод будет 10.

...