Возврат из функции объекта по ссылке

273
20 декабря 2016, 22:51

Изучаю С++ по книге С. Прата, пример взят из книги. Определен класс со следующей функцией:

const Stock & Stock::TopVal(const Stock & _st) const
{
    if (_st.total_val > total_val)
        return _st;
    else
        return *this;
}

Теперь в main() создаю массив объектов типа Stock и присваиваю указателю top значение одного из элементов массива:

for (int st = 1; st < STKS; st++)
{
    top = &top -> TopVal(stocks[st]);
}

Объясните, почему при присваивании указателю top значения из функции TopVal следует указывать знак ссылки, ведь из функции уже передается ссылка?

Answer 1

Из функции передается ссылка, но ссылка - это как бы псевдоним, а не адрес. Т.е. если у вас есть

int x;
int& r = x;
int* p = &x;

то r - обратите внимание, инициализируется x, а не адресом, как указатель. Как именно внутренне реализована ссылка - в данном случае не играет роли.

Вы используете r вместо x - например, в присваивании r = 5;. B точно так же вы получаете адрес через ссылку - p = &x тождественно p = &r;.

Непосредственно ссылка в указатель не преобразуется, и поэтому вам нужен оператор взятия адреса для возвращаемой ссылки.

Answer 2

В этом предложении

top = &top -> TopVal(stocks[st]);
     ^^^

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

В свою очередь символ & может означать оператор взятия адреса, как в приведенной вами программе, ссылку при объявлении ссылок, а также бинарный битовый оператор AND.

Итак, в данном объявлении функции- члена класса

const Stock & Stock::TopVal(const Stock & _st) const
           ^^^                         ^^^ 
{
    if (_st.total_val > total_val)
        return _st;
    else
        return *this;
}

символ & используется для объявления ссылок. Функция возвращает ссылку на объект типа const Stock, а также объявляет в качестве параметра ссылку на объект такого эе типа const Stock.

А в этом предложении

top = &top -> TopVal(stocks[st]);
     ^^^

указателю top, который скорей всего объявлен как

const Stock *top;

присваивается адрес того объекта, ссылка на который возвращается из функции.

Чтобы было более понятно, то рассмотрите следующий пример

int x = 10;
int &r = x;
int *p = &x;
r = 20;
*p = 30;

В этом примере объявляется ссылка r на объект x и указатель p, который будет содержать адрес объекта x. Ссылку можно рассматривать как альтернативное имя объекта - как алиас объекта. То еть к области памяти, где расположен объект x, вы можете обращаться по исходному имени x, или используя имя r.

READ ALSO
Вычислить 100е число Фибоначчи

Вычислить 100е число Фибоначчи

Всем приветТакая проблема, я провожу исследования для сравнения различных методов реализации алгоритма вычисления числа Фибоначчи

326
В чем разница между константой x и &amp;xx?

В чем разница между константой x и &xx?

В чем разница между константой x и &xx?

329
Что такое standard-layout в C++ и зачем он нужен?

Что такое standard-layout в C++ и зачем он нужен?

Читал на английском, но так и не смог разобраться

305
Определение типа

Определение типа

Как определить тип результата арифметического выражения?

255