0

Suppose there are two object : num1 , num2 each store integer number of 5 .

I want to add both object's value using non member function so result is : 10 .

But THE OUTPUT show value : 5 .

Is there any error in class member function or *this pointer ?

main.cpp

#include<iostream>
#include"Person.h"  
using namespace std ;

int main(){
    Person num1 ;
    Person num2 ;

    num1.InValueCapture(5) ;
    num2.InValueCapture(5) ;

    add(num1,num2);   //non class member function  : num1+num2 expecting result : 10           
    
    cout << "THE OUTPUT : " << num1.GetValueCapture() << endl; //but now we get 5 
    return 0 ;
}

Person.h

#ifndef PERSON.H
#define PERSON.H

struct Person{
private:
    int value_capture ;
public:

    int InValueCapture(int value){
        value_capture = value ;
    }

    int GetValueCapture() const {
        return value_capture ;
    }

    //adding two data
    Person& combine(const Person &Rdata)
    {
        value_capture += Rdata.value_capture ;
        std::cout << "value capture : " << value_capture <<std::endl; // use to check value inside DataSum.value_capture

        return *this ;
    }
};



Person add(const Person &Ldata , const Person &Rdata)       //nonmember function 
{
    Person DataSum = Ldata;
    DataSum.combine(Rdata);  // add Rdata to Ldata , call class function combine
    return DataSum ;        //
}

#endif

Thank you for your guidance , appreciate your help .

  • 1
    Your add function is modifying and returning the `DataSum` object you created in it. You need to modify `LData` or `RData` if you want to see the changes applied to the object you passed to the function. – NathanOliver Jul 09 '21 at 13:55
  • Same situation: `int add(const int& a, const int& b) { int sum = a; sum += b; return sum; }`. Do you see the problem? – molbdnilo Jul 09 '21 at 13:59

2 Answers2

0

Comments are liars:

DataSum.combine(Rdata);  // add Rdata to Ldata , call class function combine

This does not "add Rdata to Ldata". You are calling a method of DataSum which is a copy of LData. Modifiying the copy has no effect on the original LData. Don't make a copy:

void add(Person &Ldata , const Person &Rdata)       //nonmember function 
{
    Ldata.combine(Rdata);  // add Rdata to Ldata , call class function combine
}

Actually I am not 100% sure what the function is supposed to do. If you want to modify the first parameter you cannot pass it as const reference. If you want to not modify it passing const reference is fine, then you can return the result, but thats already what your function does, just that you ignore the returned value. I removed the return to make it more clear that the function modifies its first parameter. Though, now the caller can as well call combine directly.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • This won't work because `combine` is, rightly, a non-`const` member function so you can't call it if `Ldata` is a `const Person&`. The actual problem is they seem to expect `add` to be mutating its arguments, instead of using the return value they've written. – Nathan Pierson Jul 09 '21 at 14:01
  • @NathanPierson realized that and removed the `const`. Now I am not sure if it should return a reference or a copy... – 463035818_is_not_an_ai Jul 09 '21 at 14:02
  • If it's actually supposed to mutate its left hand side, I don't see an immediately obvious reason for it to return anything at all. But then I don't see why you'd write a non-member `add` function that mutates its left hand side instead of `operator+=` or something. – Nathan Pierson Jul 09 '21 at 14:03
  • @NathanPierson I suppose this is just an "issue" encountered while practicing and trying out different things. The free function is rather useless when one can call `combine` directly – 463035818_is_not_an_ai Jul 09 '21 at 14:05
  • Thank you , problem solve by remove const . – KOO CHEN FENG Jul 09 '21 at 14:13
0

Change

Person add(const Person &Ldata , const Person &Rdata)

to

[[nodiscard]] Person add(const Person &Ldata , const Person &Rdata)

add is a "pure" function, in that it returns the sum of L and R.

It does not modify either.

Once you do this:

add(num1,num2);   //non class member function  : num1+num2 expecting result : 10           

this results in a compiler error, as you are doing the equivalent of x+y then discarding the result.

num1 = add(num1, num2);

does what you want.

A function called add should not modify its arguments.

Possibly you should embrace operations. Change combine to:

//adding two data
Person& operator+=(const Person &Rdata)&
{
    value_capture += Rdata.value_capture ;
    std::cout << "value capture : " << value_capture <<std::endl; // use to check value inside DataSum.value_capture

    return *this ;
}

and add to:

// notice we take Ldata **by value**, making a copy
[[nodiscard]] Person operator+(Person Ldata, const Person &Rdata)  {
  Ldata += Rdata;
  return Ldata;
}

your main code then becomes:

num1 = num1+num2;

or

num1 += num2;

both of which are very clear in what they should do.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524