2010-07-14 8 views
4

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

Я довольно много не понимаю, почему вы возвращаете * это во всех примерах, таких, как показано ниже:

Foo & Foo::operator=(const Foo & f) 
{ 

//some logic 

return *this; 

} 

Так что, если у меня есть какие-то заявления, как:

Foo f; 
f.hour = 7; 

Foo g; 
g = f; 

После запуска оператора присваивания он возвращает ссылку на объект g (* this). Так что теперь вопрос в том, не будет у меня теперь есть заявление неявно, как это ?:

g = g (g being a reference) 

Дело в том, прежде, установив ссылку на объект только вызвало бы конструктор копирования будет вызван. В этом случае он даже не подходит для подписи конструктора копирования.

+1

Не забудьте проверить самоопределение! (см. http://www.parashift.com/c++-faq-lite/assignment-operators.html#faq-12.1) –

+3

@ В silico: В качестве альтернативы напишите ваши операторы присваивания, чтобы они работали с самоназначением (что часто является результатом наличия исключающих операторов присваивания). –

+0

Мой вопрос хотя и за пределами * это: Если я вернул ссылку на объект и храню его в обычном объекте, что произойдет, если конструктор копирования не будет вызван. В моем случае я уже написал оператор присваивания, поэтому конструктор копирования не будет вызван. – Ilya

ответ

7

Вы хотите вернуть *this, так что вы можете цепи =:

Foo f, g, h; 

f = g = h; 

В основном это назначение h в g, то назначая g (возвращенное return *this) в f:

f = (g = h); 

Другая ситуация это иногда используется в присваивании в условном (многие считают, что плохой стиль):

if ((f = 3).isOK()) { 

С утверждением g = f; возвращение просто игнорируется, как если бы вы делали 3 + 4;.

+3

Или более слегка классический пример '((f = func_returning_f())! = F_to_ignore) –

4

Я думаю, вы немного путаете идею инфиксной записи. g = f не имеет значения call operator= of g with f and put the result into g это означает apply operator= on g with parameter f and set the value of this expression to the result. Это идентичное поведение с другими инфиксными операторами, такими как + или /.

Операторы на некоторых языках могут быть применены как нормальная функция (и в C++ с некоторым посторонним синтаксисом), например = (g f), которая показывает концепцию немного более четко.

Edit:

Например, что часто используется в качестве примера для IO:

// loop until some sentinel value 
while ((nextChar = (char) getchar()) != 'Q') { 
    string += nextChar; 
} 

Обратите внимание, что поскольку оператор = возвращает свой первый аргумент (nextChar в данном примере), вы можете составляете назначение и тестирование.

0

После того, как оператор присваивания работает, он возвращает ссылку на объект г (Символ * этого). Итак, теперь вопрос: теперь я не буду иметь заявление неявным образом?:

г = г (г является ссылкой)

Нет, но само назначение является то, что вам нужно проверить. То, что возвращает *this, делает значение выражения (g=f), g. Что полезно для цепочки присвоений. В заявлении, как

Foo a, b, c; 
a = b = c; 

a в настоящее время присваивается значение, возвращаемое методом operator=. Возвращаясь *, этот оператор делает то, что ожидается (значение c присваивается b, то новое значение b присваивается a).

0

Причина в том, что результатом вашего назначения может быть rvalue в другом выражении.

+2

Вызов функции, возвращающей ссылку, на самом деле является ** lvalue **. – fredoverflow

+0

@FredOverflow: Если f является функцией, возвращающей ссылку, то f() = 5 использует f() как lvalue. Но как насчет a = f(); Используется ли результат f() как rvalue? a = b = c, как a = (b = c), что аналогично a = f() –

+0

Вы связаны с вопросом C, но термины * lvalue * и * rvalue * имеют разные значения в C и C++ , (На самом деле, нет такой вещи, как «rvalue» в текущем стандарте C.) – fredoverflow

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