2017-02-16 17 views
0

Я перегрузил оператор pre-increment, используя функцию друга. В перегруженной функции друга значение переменной отображается правильно. Но это значение не отображается в функции отображения, почему?Перегрузка оператора предварительного инкремента, не отображающего правильный результат

#include <iostream> 
using namespace std; 

class Rectangle { 
public: 
    int breadth; 

public: 
    void read(); 
    void display(); 
    friend void operator ++(Rectangle r1); 
}; 
void Rectangle::read() 
{ 
    cout << "Enter the breadth of the Rectangle: "; 
    cin >> breadth; 
} 
void operator++(Rectangle r1) 
{ 
    ++r1.breadth; 
    cout<<r1.breadth<<endl; //correct result 
} 
void Rectangle::display() 
{ 
    cout<<breadth<<endl; // not showing pre-incremented value, why ??? 
} 
int main() 
{ 
    cout<<"Unary Operator using Friend Function \n"; 
    Rectangle r1; 
    r1.read(); 
    ++r1; 
    cout << "\n breadth of Rectangle after increment: "; 
    r1.display(); 
    return 0; 
} 
+1

Что такое «Rectangle r1» - указатель, ссылка или скопированный объект на основе того, с которым вы проходили? – UKMonkey

+1

Поскольку ваш оператор ++ является функцией, не являющейся членом, и увеличивает свою собственную копию прямоугольника. – tambre

+3

Вы должны реализовать оператор ++ как функцию-член. – tambre

ответ

8

Ваш operator ++ принимает Rectangle объект по значению, которое означает, что он получает копию операнда. Затем он покорно увеличивает член копии breadth, распечатывает его, а затем удаляет копию, когда она закончилась.

Вы хотите, чтобы принять параметр по ссылке:

friend void operator ++(Rectangle &r1) 
{ 
    ++r1.breadth; 
} 

отметить также, что это довольно часто перегружать унарные операторы с использованием функций-членов вместо свободных функций. Используется, как это, вы не имели бы эту проблему:

class Rectangle 
{ 
    // ... 

public: 
    void operator++() 
    { 
    ++breadth; 
    } 

    // ... 
}; 

Несколько стороны комментария:

  • Это обычно для operator++ возвращать ссылку на свой операнд, чтобы имитировать то, что встроенные оператор делать. Точно так же, как можно сделать ++ ++ i для int i, должно быть возможно сделать ++ ++ r для пользовательского типа r.

  • На практике перегрузка оператора должна использоваться только тогда, когда: a) вы пишете тип, который ведет себя аналогично встроенному типу, или b) вы пишете язык, специфичный для домена. Приращение прямоугольника не является чем-то, что я мог бы интуитивно объяснить, и лучше всего сделать его как именованную функцию-член. Как вы можете определить, увеличивает ли размер ++r ширину, высоту или и то и другое, или перемещает прямоугольник вправо или ...?

+0

Вы также должны показать решение о наличии перегруженности приращений как функции-члена. – tambre

+0

@tambre Если вы хотите показать, как это сделать правильно, вы можете обратиться к разделу [FAQ по перегрузке оператора] (http://stackoverflow.com/questions/4421706/operator-overloading). – moooeeeep

+2

Этот последний пункт пули * чрезвычайно * важен. Это очень плохое использование перегрузок. (С удачей, это плохой выбор примера проблемы учителем). –