С++ для начинающих



         

Параметры-ссылки - часть 2


class Huge { public: double stuff[1000]; };

extern int calc( const Huge & );

int main() {

    Huge table[ 1000 ];

    // ... инициализация table

    int sum = 0;

    for ( int ix=0; ix < 1000; ++ix )

        // calc() ссылается на элемент массива

        // типа Huge

        sum += calc( tab1e[ix] );

    // ...

}

Может возникнуть желание использовать параметр-ссылку, чтобы избежать создания копии большого объекта, но в то же время не дать вызываемой функции возможности изменять значение аргумента. Если параметр-ссылка не должен модифицироваться внутри функции, то стоит объявить его как ссылку на константу. В такой ситуации компилятор способен распознать и пресечь попытку непреднамеренного изменения значения аргумента.

В следующем примере нарушается константность параметра xx функции foo(). Поскольку параметр функции foo_bar() не является ссылкой на константу, то нет гарантии, что вызов foo_bar() не изменит значения аргумента. Компилятор сигнализирует об ошибке:

class X;

extern int foo_bar( X& );

int foo( const X& xx ) {

    // ошибка: константа передается

    // функции с параметром неконстантного типа

    return foo_bar( xx );

}

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

extern int foo_bar( const X& );

extern int foo_bar( X ); // передача по значению

Вместо этого можно передать копию xx, которую позволено менять:

int foo( const X &xx ) {

    // ...

    X x2 = xx; // создать копию значения

    // foo_bar() может поменять x2,

    // xx останется нетронутым

    return foo_bar( x2 ); // правильно

}

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

void ptrswap( int *&vl, int *&v2 ) {




Содержание  Назад  Вперед