2010-05-30 6 views

ответ

9

Параметр перегруженного оператора присваивания может быть любым типом и может передаваться по ссылке или по значению (ну, если тип не является конструктивным, то он не может быть передан по значению, очевидно).

Так, например, вы могли бы иметь оператор присваивания, который принимает int в качестве параметра:

MyClass& operator=(int); 

Оператор присваивания копии является частным случаем оператора присваивания. Это любой оператор присваивания, который принимает тот же тип, что и класс, либо по значению, либо по ссылке (ссылка может быть сконвертированной или нестабильной).

Если вы явно не реализуете какую-либо форму оператора присваивания копий, то он неявно объявляется и реализуется компилятором.

+0

Спасибо, Джеймс! Для оператора присваивания копий существует ли какой-либо тип класса, который не может быть скопирован? Я думаю, что у всех типов классов, по крайней мере, есть конструктор копии по умолчанию? – Tim

+0

@Tim: Конечно: если у вас есть _private_ объявленный пользователем конструктор копирования для класса, то конструктор копирования будет недоступен (если вы не являетесь членом-членом или другом этого класса), и класс не будет конструктивным. Если вы объявляете конструктор копирования, но не определяете его, то класс вообще не копирует конструкцию (и попытка копирования-конструирования экземпляра приведет к ошибкам компоновщика). Оба эти метода используются (обычно вместе), чтобы класс не был доступен для копирования. –

+0

Спасибо! Интересно, в каких случаях нужен класс, который нельзя копировать? – Tim

5

Как правило, вам решать, нет must. Первый вариант является общим и «canonic» и подходит для любой реализации оператора присваивания.

Если у вас вопрос, скорость, я думаю, вы должны прочитать this article о технике передачи по значению. Это означает, что в некоторых случаях передача по значению будет более эффективной, чем передача по ссылке const.

Кроме того, для второго варианта не требуется ключевое слово const, потому что передача по значению действует так, как если бы была создана копия, поэтому исходный объект определенно не будет изменен.

+0

Спасибо Kotti! Грубо прочитайте его, но не совсем понимаете, почему передача по ссылке медленнее, чем передача по значению? – Tim

+0

Ну, обычно это не так, но пункт этой статьи состоит в том, что если вы делаете копию объекта сразу после ее передачи по ссылке, это будет медленнее, чем передача по значению и назначение этой копии из-за оптимизации компилятора. Это на самом деле сложно, но не совсем бессмысленно ... –

5

C++ Operator Overloading Guidelines предположить, что оператор присваивания получает ссылку на константу. Согласно сайту, причина в том, что мы не хотим изменять аргумент (начиная с const), а только с левой стороны оператора. Таким образом, это экономит время, чтобы передать его по ссылке.

Он также указывает на причину, почему также ссылка возвращается оператором присваивания - цепью оператора. Чтобы получить a = (b = 1), необходимо, чтобы (b = 1) возвращал ссылку, которая может быть назначена (=) на номер a.

+0

Отличная ссылка ... –

3

Знаете ли вы, что копия и своп idiom для исключения безопасного назначения?

MyClass& operator=(const MyClass& rhs) 
{ 
    MyClass copy(rhs); 
    swap(copy); 
    return *this; 
} 

Реализация может быть упрощена (и в некоторых случаях ускорило) через вызов по значению:

MyClass& operator=(MyClass copy) 
{ 
    swap(copy); 
    return *this; 
} 
-2

Ok У меня была эта проблема, и я не мог найти хороший ответ, так что я собираюсь поделиться тем, что узнал.

Вы можете пройти по значению, в этом нет ничего плохого. (как вы показали в своем вопросе.)

Но причина, по которой мы передаем параметр по ссылке const, заключается в том, что функция не делает фактическую копию вызываемого значения. Его ссылка на нее, поэтому ее просто указывая на это где бы он ни находился в памяти.

Это экономит время обработки, особенно если его что-то большое, имеющее тысячи имен ... В этом случае сохраненное время будет практически ничем.

И для константы, которая гарантирует пользователю функцию, что ссылочное значение не будет изменено, поскольку оно может быть изменено, так как у вас есть доступ к исходному местоположению в памяти, потому что он передан по ссылке .. Если ваше определение функции фактически изменяет значение параметра, вызываемого в const-ссылке, это будет ошибка компилятора, это не позволит вам это сделать. потому что когда вы ставите const, вы говорите компилятору, что это значение не может быть изменено.

+0

Рассмотрите возможность обсуждения в комментариях. – wizulus

+0

Что это значит? Извините, что я новичок, я думал, что я написал комментарий. – 3366784

+0

Вопрос или ответ имеет большое количество и стрелки вверх и вниз с левой стороны. Под каждой из них есть ссылка, в которой говорится «Добавить комментарий». Нажатие на это даст вам простое текстовое поле, чтобы ввести комментарий, например тот, который вы только что использовали. То, что вы делали раньше, входило в ** ответ ** в нижней части страницы в разделе под названием ** «Ваш ответ **. Добро пожаловать в StackOverflow :) – wizulus

Смежные вопросы