1
#include <iostream>
using namespace std;
class Complex{
private:
    double real_;
    double imag_;
public:
    void set(double m, double n){
        this->real_ = m;
        this->imag_ = n;
    }
    void addTo(Complex add){
        this->real_ += add.real_;
        this->imag_ += add.imag_;
    }
};
int main(){
    Complex a, b, c;
    a.set(1.1, 2.2);
    b.set(1.1, 2.2);
    c.set(1.1, 2.2);
    a.addTo(a).addTo(b).addTo(c);   // problem.

    return 0;
}

I have to use that expression (a.addTo(a).addTo(b).addTo(c);).

How can I use a method of class continuously in the main function?

When compiling, it says that the class type should come in front of .addTo(b), and if I change from void addTo to Complex addTo, I need to set the return value, then, how can I return a, which called addTo?

Piotr Siupa
  • 3,929
  • 2
  • 29
  • 65
Atoro
  • 11
  • 1
  • 1
    Try making `addTwo`'s return type a `Complex &` and return `*this`. (Also you have a few unrelated typos in your code, e.g. too few semicolons and `addTo` instead of `addTwo`) – mediocrevegetable1 Oct 13 '21 at 07:30
  • You have to return the current object reference with *this in your 'addTwo' method. – MiniMik Oct 13 '21 at 07:31
  • `addTwo` or `addTo`? – Some programmer dude Oct 13 '21 at 07:32
  • Instead of writing plain functions you could write operators which would make using you class a lot easier. I'd recommend to read up on constructor, `operator+`, `operator=` and maybe `operator+=`. After you understand how they work, they are not much harder to write than function and they allow you to use your class in math-like expression, e.g. `a = a + b + c;`. – Piotr Siupa Oct 13 '21 at 07:42
  • I forgot the semicolon while copying the code I wrote. And the function is addTo. I wrote addTwo wrong. Thank you so much for your answer. I should try it. – Atoro Oct 13 '21 at 07:42
  • 2
    What you are looking for is called a fluent interface. You achieve this as mentioned by @mediocrevegetable1. See this post https://stackoverflow.com/questions/2084503/whats-a-fluent-interface – Jan Gabriel Oct 13 '21 at 07:42
  • I slowly read all the answers you gave me, and I understood. Thank you so much. All – Atoro Oct 13 '21 at 08:01
  • Whilst your immediate question has been answered, a Complex type is normally considered as a value type. @NO_NAME has made a good suggestion for improving your class interface using operator overloading. Thus, `Complex operator +(const Complex other) { return Complex{this->real_ + other.real_, this->imag_ + other.imag_}; }` which makes `c = a + b;` possible. – Daniel Dearlove Oct 13 '21 at 08:26

3 Answers3

1

Your function is void and returns nothing that why you cannot use a method of class continuously. You need to change the return type from void to Complex &

Complex& addTo( Complex add )
  {
      this->real_ += add.real_;
      this->imag_ += add.imag_;
      return *this;
  }

And you should pass a ref instead of value.

You can ref this link for more information: https://en.wikipedia.org/wiki/Fluent_interface

Le Ngoc Thuong
  • 279
  • 2
  • 8
1

You are close. As mentioned in the comments, your addtwo() function needs to return a reference to the class being added. You can do that by returning the dereferenced this pointer for that instance. Since this is a pointer to the current instance, to return a reference to type Complex you will need to dereference this removing the one level of pointer indirection making the return type Complex, e.g.

  Complex& addTwo(Complex add){
      this->real_ += add.real_;
      this->imag_ += add.imag_;
      return *this;
  }

While using a setter is fine to provide the initial values to the instance of your class, you really ought to write a constructor for the class to accomplish the same thing. You can add default value of 0 for each real_ and imag_ at that point, e.g.

public:
  Complex (double real = 0, double imag = 0) : real_(real), imag_(imag) {}

Now you can initialize the Complex instances at the time they are created, e.g. in main()

  Complex a {1.1, 2.2}, 
          b {1.1, 2.2}, 
          c {1.1, 2.2};

Adding a friend function for std::ostream& is a simple way to provide stream-based output operator for your Commplex type, e.g.

    friend std::ostream& operator << (std::ostream& os, const Complex& c) {
        std::cout << "{" << c.real_ << "," << c.imag_ << "}\n";
        return os;
    }

Putting it altogether, you can write what you are attempting as follows, initializing each instance of Complex through the constructor while having your set() function available to change values for an instance, if needed.

#include <iostream>

class Complex{
private:
  double real_;
  double imag_;

public:
  Complex (double real = 0, double imag = 0) : real_(real), imag_(imag) {}
  
  void set(double m, double n){
    this->real_ = m;
    this->imag_ = n;
  }

  Complex& addTwo(Complex add){
      this->real_ += add.real_;
      this->imag_ += add.imag_;
      return *this;
  }
  
    friend std::ostream& operator << (std::ostream& os, const Complex& c) {
        std::cout << "{" << c.real_ << "," << c.imag_ << "}\n";
        return os;
    }
};

int main(){
  
  Complex a {1.1, 2.2}, 
          b {1.1, 2.2}, 
          c {1.1, 2.2};
  
  a.addTwo(a).addTwo(b).addTwo(c);
  
  std::cout << a;
}

Example Use/Output

$ ./bin/complex_class
{4.4,8.8}

Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
-2
#include <iostream>
using namespace std;
class Complex{
private:
  double real_;
  double imag_;
public:
  void set( double m, double n )
  {
    this->real_ = m;
    this->imag_ = n;
  }

  Complex& addTo( Complex add )
  {
      this->real_ += add.real_;
      this->imag_ += add.imag_;
      return *this;
  }
};

int main(){
  Complex a, b, c;
  a.set( 1.1, 2.2 );
  b.set( 1.1, 2.2 );
  c.set( 1.1, 2.2 );
  a.addTo( a ).addTo( b ).addTo( c );   // No problem.

  return 0;
}
MiniMik
  • 268
  • 1
  • 10
  • You should explain what changes you have made to the original code in the answer, otherwise it's difficult at first to tell and understand what has been changed and why. In its current state, this answer feels incomplete IMO. – mediocrevegetable1 Oct 13 '21 at 07:37
  • 1
    This answer would really benefit from an explanation of why this change works. – Piotr Siupa Oct 13 '21 at 07:37
  • As NO_NAME and mediocrevegetable mentioned, your post will benefit from an explanation of why it works. – Jan Gabriel Oct 13 '21 at 07:48
  • It was my first question, so there were many shortcomings. Next time, I'll write the exact code and ask the question. – Atoro Oct 13 '21 at 08:04