Return a reference by a class function and return

2019-06-25 05:33发布

Operator overloading in class CVector:

CVector CVector::operator+ (CVector param) {
  CVector temp;
  temp.x = x + param.x;
  temp.y = y + param.y;
  return (temp);
}

and in main:

CVector a (3,1);
  CVector b (1,2);
  CVector c;
  c = a + b;

So an object is passed by value, and then another temp object is being created. I guess b is being passed by value, a is the one calling the + therefore the x and y belong to a and pram.x and param.y to b. temp is returned and the the copy assignment operator delivers temp's values to c?

But what about this:

CVector& CVector::operator= (const CVector& param)
{
  x=param.x;
  y=param.y;
  return *this;
}

and in main:

a=b;

Again a is calling the = and b is being passed by reference as const.(in this case does it matter if it was passed by value?) This is where i get confused, x belonging to a is assigned param.x of be. so why isn't this function void, since x and y can be accessed by this function. What does return *this means, i know that this is the address of the object calling the function, so *this would be the function itself, but if we are returning an object we need to assign it it somewhere like the previous c=temp after temp=a+b? And what does CVector& even mean, it doesn't look like we are expecting an address of an object of CVector type?

In other words why isn't the function just:

void CVector::operator= (const CVector& param)
    {
      x=param.x;
      y=param.y;
    }

??

Then there is this code

#include <iostream> 
using namespace std;
 class Calc { 
private: 
  int value; 
public: 
  Calc(int value = 0) { this->value = value; } 
  Calc& Add(int x) { value += x; return *this; } 
  Calc& Sub(int x) { value -= x; return *this; } 
  Calc& Mult(int x) { value *= x; return *this; } 
  int GetValue() { return value; } }; 

int main() { 
  Calc cCalc(2); 
  cCalc.Add(5).Sub(3).Mult(4); 
  cout << cCalc.GetValue(); 
  return 0; 
}

Now if i removed the & from the functions:

  Calc Add(int x) { value += x; return *this; } 
  Calc Sub(int x) { value -= x; return *this; } 
  Calc Mult(int x) { value *= x; return *this; } 

and used

Calc cCalc(2)
cCalc.Add(5);
cCalc.Sub(3);
cCalc.Mult(4);

instead of the former, it would produce the same resault. So why does Calc& returne type allow chaining.

I not only want to know how to program, since object oriented is much writing by a pattern (this is written like this, this is needed if that) opposed to structured programming where you have to use logic, but also to know why is a peace of code defined as it is, and why it isn't as i intuitively think it should be(although i only learn programming for about a year).

Thanks!

2条回答
ら.Afraid
2楼-- · 2019-06-25 06:14

First, the usual convention in C++ is to pass class type arguments as references to const. There are clearly exceptions (predicate objects or iterators in the standard library), but in application level code, passing a class type by reference to const is ubiquitous enough to justify a comment:

Vector
Vector::operator+( Vector const& rhs ) const
{
    //  ...
}

Or more likely:

Vector
operator+( Vector const& lhs, Vector const& rhs )
{
    Vector results( lhs );
    results += rhs;
    return results;
}

Another widespread convention is to make such binary operators free functions, so that both the left and right arguments ar treated in the same fashion. And to implement them in terms of =, so as to ensure that = and have the desired relation.

For operators which modify the left argument, like the assignment operators, it is on the other hand the convention to make them members; the operator= must in fact be a member. A free function Vector& operator+=( Vector& lhs, Vector const& rhs ) would be legal, but rather unusual.

As for why operator= returns Vector&: convention. It most accurately simulates what the built in operators do:

int&
MyClass::funcWithInt( int newValue )
{
    return myInt = newValue;
}

is legal (even if many, myself included, would consider it bad stype), so the same code should be legal with a class type which overloads operator=. And of course, the compiler generated operator= will return a reference to const, so there's a strong argument for doing the same when you write one yourself.

查看更多
一夜七次
3楼-- · 2019-06-25 06:17

so why isn't this function void, since x and y can be accessed by this function. What does return *this means

Since operator=() is declared to return a reference, return *this; returns a reference to the current object. This allows us to chain assignment operators. For example,

a = b = c;

will call b.operator=(c); and return a reference to b. Then a is assigned by a call which is equivalent to a.operator=(b).

查看更多
登录 后发表回答