2016-09-03 2 views
4

Я изучаю C++, но мне трудно понять, как объекты возвращаются функцией-членом/методом. Я следую за «Научим себя C++ в 21 день».Возвращение путаницы объекта

Итак, я понимаю классы и объекты, а не просто о возвращении объекта. Я приведу пример (в настоящее время обучая перегрузку оператора).

const Counter& Counter::operator++() 
{ 
    ++itsVal; 
    return *this; 
} 

Я просто очень смущен обратным типом. Этот метод говорит, что он должен возвращать ссылку на объект счетчика, но когда объект разыменовывается с

return *this; 

Разве мы не просто возвращающий объект счетчика класса? Почему заголовок функции говорит, что мы возвращаем ссылку на объект-счетчик? Почему заголовок метода просто не говорит о том, что возвращаемый тип является объектом типа Counter? Здесь я смущаюсь: \

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

+1

возвращающий объект класса Couter создаст копию (второй экземпляр), таким образом, основная идея программирования состоит в том, чтобы иметь оператор точки для одного и того же экземпляра объекта. Извините, мой английский, больше не могу объяснить. –

+1

согласен с @Sam Varshavchik, технология многоточечного оператора продвинута (такое обозначение является частью этого). Изучите базовый по значению/по ссылочному примеру. –

+1

Вы уверены, что есть 'const'? Это очень нетрадиционно и непрактично, и в отличие от встроенного префикса '++'. –

ответ

5

Разве мы не возвращаем объект класса Counter?

Да, мы возвращаем объект. Но он возвращается по ссылке или по значению, определяется типом возвращаемого значения в объявлении функции, мы не можем определить (или различать) их в инструкции return.

const Counter& Counter::operator++() // return by reference (to const) 
{ 
    ++itsVal; 
    return *this; 
} 

Counter Counter::operator++()  // return by value. Note the body of function is the same. 
{ 
    ++itsVal; 
    return *this; 
} 

Кстати: Возвращаясь со ссылкой на const (и по значению, приведенном выше примере используется только для иллюстрации) для префикса operator++ не имеет смысла. Он должен возвращать ссылку на не-const на самом деле. Такие, как

Counter& Counter::operator++() // return by reference (to non-const) 
{ 
    ++itsVal; 
    return *this; 
} 
+3

BTW: Изучение C++ «Научите себя C++ за 21 день», кажется, плохая идея. – songyuanyao

+0

Почему? Вы слышали плохие вещи о книге? – Pistax

+3

@Pistax (1) Это вводит в заблуждение. Невозможно понять C++ за 21 день. (2) Проверьте [здесь] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) для лучшей книги. – songyuanyao

1

возврата * это;

Разве мы не возвращаем объект класса Counter?

Нет, это возвращает ссылку на объект.

Оператор * является оператором разыменования. Результатом этого оператора является ссылка на объект, на который указывает указатель. this - указатель.

Дело в том, что при использовании в контексте без ссылки они автоматически получают «преобразование» к ссылочному объекту.

T *t; 

// ... 

T u = *t; 

Результат оператора * это, как сказано, ссылка. Затем результат используется в контексте без ссылки, а именно присвоении другому объекту, который сам по себе не является ссылкой. Это заканчивается тем, что разрешает ссылающийся объект, в результате чего создается копия.

Вводные праймеры C++ часто указывают, что '* p' разрешает объект, на который указывает указатель. Это всего лишь небольшая белая ложь. Это справедливо только в контексте без ссылки.Это оставляет промежуточную стадию разрешения ссылки, а затем разрешает ссылку на ссылочный объект.

На данный момент в типичной вводной справочной литературе C++ ссылки еще не воспитывались как тема. Поэтому этот промежуточный шаг не учитывается, чтобы избежать путаницы. Но теперь, когда вы знаете что-то о ссылках, вам нужно выполнить некоторую перестройку умственного снаряжения:

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

+0

Результат '* t' - это lvalue типа' T'. Не ссылка (что бы это ни подразумевалось), конечно, не 'T &'. Нет такой вещи, как «ссылочный контекст» и «контекст без ссылки». Каждая часть вашего ответа бессмысленна и запутанна. –

1

Метод возвращает сам объект класса после изменения объекта с помощью itsVal плюс 1.

Вы можете использовать counter_object++ для самоинкремента, а затем вызвать функцию else. Например, (counter_object++).func(), не создавая другого объекта.

2

Так я думаю о нем, что, поскольку речь идет в основном псевдоним к чему-то, возвращая разыменованный указатель будет как возвращение объектов псевдоним

Да, это точно. Функция возвращает псевдоним объекта, на который была вызвана функция. Он не возвращает копию этого объекта.

Вызывающий код может выглядеть следующим образом:

Counter c; 
do_something(++c + 5); 

С ++c вернулся псевдоним c, этот код будет вести себя как:

++c; 
do_something(c + 5); 

без внесения каких-либо ненужных копий c.

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