0

Tried to overload operator+ but looks like there is an unwanted side effect, it modifies one of the arguments. How am I supposed to do it?

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class BookShelf
{
    vector<string> m_books;

public:
    BookShelf(const vector<string>& books)
        : m_books(books)
    {

    }

    BookShelf& operator+(const BookShelf& bookshelve)
    {
        for (const auto& b : bookshelve.m_books)
            m_books.push_back(b);

        return *this;
    }

    void print()
    {
        for (const auto& book : m_books)
            cout << book << " ";
        cout << endl;
    }
};


int main()
{
    BookShelf b1{{"abc", "def"}};
    b1.print();

    BookShelf b2{{"ghi", "jlm", "nop"}};
    b2.print();

    BookShelf b3 = b1 + b2;
    b3.print();

    b1.print();
    b2.print();
}

The above returns:

abc def 
ghi jlm nop 
abc def ghi jlm nop 
abc def ghi jlm nop 
ghi jlm nop 
KcFnMi
  • 5,516
  • 10
  • 62
  • 136
  • you write one that doesn't modify one of the arguments? It's not a "side effect" - you *told* the computer to do that. – user253751 Feb 09 '23 at 17:23
  • 3
    You've implemented what is more traditionally known as `operator+=`. You modify the left hand operand, and return a reference to it. The usual idea for `operator+` is that you create a new `BookShelf` and return it by value. – Nathan Pierson Feb 09 '23 at 17:24
  • You mean create using operator new? A local variable wont exist after function goes out of scope, I'm thinking – KcFnMi Feb 09 '23 at 17:25
  • Admittedly I used the word "new", but I very much _did not_ mean using `new` the C++ keyword. – Nathan Pierson Feb 09 '23 at 17:26
  • 2
    "A local variable won't exist after function goes out of scope" yes, that's why I said return it _by value_. – Nathan Pierson Feb 09 '23 at 17:26
  • It will certainly exist, if you `return` it. – Sam Varshavchik Feb 09 '23 at 17:26
  • 1
    You can write an operator that starts by copying the current object e.g. `BookShelf operator+(const BookShelf& b) const { BookShelf result{*this}; /* modify result */ ; return result; }`. Returning by value is important here. (Alternatively, you can take the argument by value so that gets copied instead, providing a fresh object you can return at the end.) – chi Feb 09 '23 at 17:31
  • Got it! May I ask, which way is better? First one might be one loc shorter. – KcFnMi Feb 09 '23 at 17:48

0 Answers0