1

I am learning C++ by studying Visual C++ textbook.
When I want to overload operator+, the code I've used for overloading operator= went wrong.

#include <iostream>
#include <string.h>
using namespace std;
//This demo shows how default operator may cause conflict, so we use overloaded operator instead
class String{
    private:
        char* string;
        int len;
    public:
        String(const char*);
        String();
        ~String(){delete [] string;}
        String& operator=(String&);     //In the book it used //String & operator=(String&) but it went wrong
                                        //String object which returned by + only got value, not an initiated object
        String operator+(String&);      //Opreator +
        void show_string(){
            cout << "String: " << string << " \tString Address: " << (void*)string << " \tLength: " << len << endl;
        }
};

String::String():len(0){        //Constructor with no argument
    string = new char[len+1];
    string[0] = '\0';
}

String::String(const char* i_string):len(strlen(i_string)){ //Constructor
    string = new char[len+1];
    strcpy(string,i_string);
}

String& String::operator=(String& str_ref){     //Overloading operator =
//The function get reference and return itself
    delete [] string;
    cout << "Overloading Operator =...\n";
    len = str_ref.len;
    string = new char[len+1];
    strcpy(string,str_ref.string);
    return *this;
}

String String::operator+(String& str){
    cout << "Overloading Operator +...\n";
    char* strbuf = new char[len+str.len+1];
    strcpy(strbuf,string);
    strcat(strbuf,str.string);
    String retstr(strbuf);
    delete [] strbuf;
    return retstr;      //call by value coz we made a new String
}

int main(){
    String A_string("My ");
    String B_string("string"),C_string;
    cout << "Show (A_string+B_string)...\n";
    (A_string+B_string).show_string();
    C_string = A_string + B_string;
    cout << "Show C_string...\n";
    C_string.show_string();
return 0;
}

It's strange because it did well when only use operator+ or operator= individually.

String A_string("Apple");
String B_string;
B_string = A_string;

(A_string+B_string).show_string();

Here's the error

In function 'int main()':
56:11: error: no match for 'operator=' (operand types are 'String' and 'String')
  C_string = A_string + B_string;
           ^

note: candidate is:
note: String& String::operator=(String&)
 String& String::operator=(String& str_ref){  \\Overloading operator =
         ^
note:   no known conversion for argument 1 from 'String' to 'String&'

I thought I can use String for argument String&, which was told in the book.
So I changed argument of operator= to String, and it works.

String& operator=(String&);

to

String& operator=(String);

Now I am confused when to use reference or String only.

Vlad from Moscow
  • 224,104
  • 15
  • 141
  • 268
Kevin Lin
  • 13
  • 1
  • 4
  • Your comment starting "In the book" makes no sense, that is the same code – M.M Jul 28 '17 at 10:44
  • Your object will misbehave at runtime because it doesn't have a correct copy-constructor – M.M Jul 28 '17 at 10:44
  • Should be `String& String::operator=(const String&)`. Looking for a dupe. – Baum mit Augen Jul 28 '17 at 10:45
  • `operator+` should take `(String const&)` too – M.M Jul 28 '17 at 10:45
  • Temporary cannot bind to non const lvalue reference. – Jarod42 Jul 28 '17 at 10:47
  • Your `String& String::operator=(String&)` takes lvalue reference to `String`, `String operator+(String&)` returns rvalue reference. You cannot bind rvalue references to lvaude reference. Canonical form of operator copy takes reference to `const` i.e. `const String&`. It will help to compile your code. BTW read also about [rule of three](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) and about [copy and swap idiom](https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) which makes copy assignment operator exception safe. – Viktor Jul 28 '17 at 10:51

1 Answers1

0

In this statement

C_string = A_string + B_string;

there is created a temporary object of the type String as result of executing the operator

String operator+(String&);      

You may not bind a non-constant lvalue reference to a temporary object.

Either rewrite/add the assignment operator like

String& operator=( const String&);     
                   ^^^^

or add a move assignment operator.

String& operator=( String &&);     
                          ^^
Vlad from Moscow
  • 224,104
  • 15
  • 141
  • 268