Тема: Перезавантаження оператора і передача об’єкта за посиланням

Привіт, форумчани!

Маю наступний код із книги Герберта Шилдта:

#include <iostream>
#include <string.h>
#include <cstdlib>

using namespace std;

class myclass {
    char *s;
public:
    /* Constructor */
    myclass() { s = new char('\0'); }
    /* Copy constructor */
    myclass(const myclass &ob);
    /* Destructor */
    ~myclass() { if (s) delete [] s;
                cout << "Free memory, allocated for s.\n"; }
    void show() { cout << s << '\n'; }
    void set(char *str);
    /* Overloaded "=" operator */
    myclass operator=(myclass &obj);
};

/* Overloading "=" operator */
myclass myclass::operator=(myclass &obj) {
    /* If there is not enough memory, than
     * allocating new block of memory */
    if (strlen(obj.s) > strlen(s)) {
        delete [] s;
        s = new char[strlen(obj.s) + 1];
    }
    
    strcpy(s, obj.s);
    
    return *this;
}

/* Copy constructor */
myclass::myclass(const myclass& ob) {
    s = new char[strlen(ob.s) + 1];
    strcpy(s, ob.s);
}

/* Loading string */
void myclass::set(char* str) {
    s = new char[strlen(str) + 1];
    strcpy(s, str);
}

/* This function returns object of type sample */
myclass input() {
    char instr[80];
    myclass str;
    
    cout << "Input string, please: ";
    cin >> instr;
    
    str.set(instr);
    
    return str;            
}

/*
 * 
 */
int main(int argc, char** argv) {
    myclass a, b;
    
    a.set((char *) "Hello!");
    b.set((char *) "Hi!");
    
    a.show();
    b.show();
    
    a = b;
    
    a.show();
    b.show();
    
    a = input();
    a.show();

    return 0;
}

Коли я намагаюсь скомпілювати його, то отримую наступні помилки:

main.cpp:79:15: error: no match for ‘operator=’ in ‘a = input()()’
main.cpp:79:15: note: candidate is:
main.cpp:24:9: note: myclass myclass::operator=(myclass&)
main.cpp:24:9: note:   no known conversion for argument 1 from ‘myclass’ to ‘myclass&’

Програма працює, якщо змінити ці два рядки:

myclass operator=(myclass &obj);
myclass myclass::operator=(myclass &obj)

Наступним чином:

myclass operator=(myclass obj);
myclass myclass::operator=(myclass obj)

Але тоді ми не передаємо посилання на об’єкт, а копіюємо його.
Або якщо змінити функцію input() наступним чином:

myclass &input()

Але тут ми передаємо посилання на локальну змінну.

Функція input() повертає об’єкт myclass, чому рядок a = b працює, а рядок a = input() - ні?

Білий Лунь

2 Востаннє редагувалося koala (02.06.2015 11:52:49)

Re: Перезавантаження оператора і передача об’єкта за посиланням

Який компілятор? Тут якраз тонке місце, яке іноді буває проблемним, із якого виростає одна з основних фішок C++11.
input повертає тимчасовий об'єкт, працювати з яким трохи незручно. Якщо не хочете займатися правилом трійки чи п'ятірки, то просто зробіть

myclass operator=(const myclass &obj)

воно і коректніше (ми ж obj не змінюємо, то хай буде const), і працюватиме як слід.

І почитайте про посилання на rvalue (&&) в C++11, це якраз ваш випадок.

Подякували: 0x9111A, Arete, Chemist-i, Ярослав4

3

Re: Перезавантаження оператора і передача об’єкта за посиланням

Компілятор: g++ (Debian 4.7.2-5) 4.7.2
Ваше рішення допомогло. Програма скомпілювалась без помилок.
Про rvalue почитаю.
Дякую, koala!

Білий Лунь

4

Re: Перезавантаження оператора і передача об’єкта за посиланням

Там, здається, тільки найпростіші фічі C++11 підтримуються, так що про rvalue-посилання - тільки для власного розвитку. Але почитайте, корисно.

Подякували: Ярослав1