Справочные параметры Адрес автоматически НЕ передан

У меня есть следующая проблема со ссылочными параметрами: Когда у нас есть функция со ссылочными параметрами, компилятор автоматически передает этой функции адрес любого аргумента, с которым она вызывается. Пример (с объектом):

class sample {
char *s;
public:
    sample(); // normal constructor
    sample(const sample &ob); // copy constructor
    ~sample( ) { if(s) delete [] s; cout << "Freeing s\n"; }
    void show() { cout << s << "\n"; }
    void set(char *str);
};// Definition will be excluded from here`

и у нас есть функция со ссылочными параметрами этого экземпляра класса,

лайк:

void funtionWithRef(sample &kk); // declaration
void funtionWithRef(sample &sam){ // definition
    sam.show();
}

и одна функция с возвращаемым объектом типа sample:

sample functionReturnSample(); //declaration
sample functionReturnSample(){ // definition
    sample sam;
    sam.set("test sample");
    return sam;
}

Теперь, когда мы делаем:

int main() {
    sample temp = functionReturnSample();
    funtionWithRef(temp);

    return 0;
}

Работает отлично. Когда мы помещаем временный объект в качестве аргумента funtionWithRef, компилятор передает адрес этого объекта в функцию. Но ПОЧЕМУ это не работает, если мы НЕ назначаем сначала возвращаемое значение functionReturnSample экземпляру, а напрямую помещаем этот метод в качестве аргумента, например:

funtionWithRef(functionReturnSample());

Почему это отличается, когда мы делаем то же самое, и согласно некоторым книгам, с которыми я консультировался, то ДОЛЖЕН

РЕДАКТИРОВАТЬ

@user657267 Это полный пример (исходная книга: C++ с нуля, 3-е издание, стр. 219-320):

class sample {
    char *s;
    public:
        sample(); // normal constructor
        sample(const sample &ob); // copy constructor
        ~sample( ) { cout << "s: " << s <<" ,Freeing s\n"; if(s) delete [] s;}
        void show() { cout << s << "\n"; }
        void set(char *str);
        sample operator=(sample &ob); // overload assignment
};
// Normal constructor.
sample::sample() {
    s = new char('\0'); // s points to a null string.
    cout << "Normal constructor: s: " << strlen(s) << endl;
}
// Copy constructor.
sample::sample(const sample &ob) {
    cout << "Copy constructor: ob.s: "<< ob.s << " ,strlen(ob.s): " <<  strlen(ob.s) << "\n";
    s = new char[strlen(ob.s)+1];
    strcpy(s, ob.s);
}
// Load a string.
void sample::set(char *str) {
    s = new char[strlen(str)+1];
    strcpy(s, str);
}
// Overload assignment operator.
sample sample::operator=(sample &ob) {
    /* If the target memory is not large enough
    then allocate new memory. */
    cout << "operator= strlen(ob.s): " << strlen(ob.s) << " ,strlen(s): " << strlen(s) << endl;

    if(strlen(ob.s) > strlen(s)) {
        cout << "operator= Larger memory of target object. Deleting current...\n";
        delete [] s;
        s = new char[strlen(ob.s)+1];
    }
    strcpy(s, ob.s);

    return *this;
}
// Return an object of type sample.
sample input() {
    char instr[80];
    static sample str;
    cout << "Enter a string: ";
    cin >> instr;
    str.set(instr);

    return str;
}

int main() {
    sample ob;
    // assign returned object to ob
    ob=input(); // This is now OK
    ob.show();

    return 0;
}

Это не скомпилируется и сообщает об ошибке:

**error: no match for ‘operator=’ (operand types are ‘sample’ and ‘sample’)**

Так что это копия / прошлое кода из упомянутой книги. Вы можете проверить, пожалуйста.

Однако я придумываю, если я укажу аргументы оператора overloaded =, которые будут выглядеть как:

 sample operator=(const sample &ob); // overload assignment

Тогда это работает. Однако, что меня беспокоит, так это то, что теперь, когда у меня есть исполняемый код, я не понимаю, почему вызывается ДВА раза конструктор копирования. Я знаю, что она вызывается, когда функция input() возвращается и создает временный объект, но я не понимаю, почему второй раз, насколько я знаю (но, возможно, я ошибаюсь), конструкторы копирования НЕ вызываются для операций присваивания (та же книга, стр. 291-292), но, похоже, несмотря на это, когда возвращаешь *this; вызывается (когда перегруженный оператор возвращает значение), вызывается конструктор копирования? Так что по этому поводу? Thankx

0 ответов

Другие вопросы по тегам