«opperator = должен принимать параметр (конечно же, const best) ref из src obj», я вижу это во многих книгах, но вместо этого я пытаюсь использовать non-ref, он также работает! Итак, какова цель использования ref? это просто, чтобы избежать копирования из param? мой тестовый код
#include <iostream>
#include <string>
using namespace std;
class Student{
public:
Student& operator=(Student);
string name;
int num;
};
Student& Student::operator=(Student s)
{
name=s.name;
num=s.num;
return *this;
}
int main(){
Student src;
src.name="haha";
src.num=11;
cout<<src.name<<" "<<src.num<<endl;
Student dst=src;
cout<<src.name<<" "<<src.num<<endl;
}
Здесь действительно две проблемы:
1) Оператор копирования-назначения, который вы определили не вызывается. Линия
Student dst=src;
не вызывает оператор копирования-назначения! Это вызывает конструктор копирования, который неявно определяется компилятором. Однако, если вы написали
Student dst;
dst = src;
затем operator=
будет называться.
2) Да, цель состоит в том, чтобы избежать копирования. Когда вы вызываете функцию, в том числе operator=
, который занимает Student
по значению Student
Аргумент объекта должен быть скопирован (посредством неявного вызова конструктора копирования). С другой стороны, если функция берет ссылку, то копия не создается.
Потому что в противном случае он будет передан по значению, которое является копией, поэтому вам нужно будет вызвать конструктор копирования, чтобы вызвать конструктор копирования …
это
Student& Student::operator=(Student s)
{
name=s.name;
num=s.num;
return *this;
}
Должно быть
Student& Student::operator=(const Student &s)
{
if (this == &s) return *this;
name=s.name;
num=s.num;
return *this;
}
Используйте ссылки, чтобы избежать потери ресурсов процессора
Просто. Посмотрите на этот код.
Student a, b;
a = b;
это равно
a.operator=(b);
а также b
передается по значению. Итак конструктор копирования называется.
a.operator=(Student(b)); // please notice that it is just psudo code..
Поэтому есть два копирование! Один конструктор копирования, а другой оператор копирования. Это ненужно.
Более того, конструктор копированияПараметр тоже должен быть ссылочным. В противном случае бесконечная рекурсия происходит потому, что вызов по значению требует копирования, а копирование требует вызова по значению и …
В C ++ 03, проходя мимо const
ссылка избегает создания потенциально дорогой новой копии только для местного s
, который никогда не изменяется, кроме копирования s
в объект назначения.
В C ++ 11 теперь у нас есть семантика перемещения: назначение может привести к передаче ресурса новому объекту или копированию ресурса. Операция передачи по копии может быть использована для получения скопированных данных, которые используются для объекта назначения, поэтому накладные расходы используются с пользой. Если вы переходите с помощью move
, нет копии. Лучшая практика в C ++ 11 состоит в том, чтобы позволить одной функции выполнять функции оператора копирования и перемещения:
Student& Student::operator=(Student s)
{
name = std::move( s.name );
num = s.num;
return *this;
}