|
Программирование >> Инициализация объектов класса, структура
#include <vector> параметр-сс1лка occurs содержит второе возвращаемое значение vector<int>::const iterator look up( const vector<int> &vec, int value, искомое значение int &occurs ) количество вхождений res iter инициализируется значением следящего за конечн элемента vector<int>::const iterator res iter = vec.end(); occurs = 0; for ( vector<int>::const iterator iter = vec.begin(); iter != vec.end(); ++iter ) if ( *iter == value ) if ( res iter == vec.end() ) res iter = iter; ++occurs; return res iter; Третий случай, когда использование параметра-ссылки может быть полезно, - это большой объект тина класса в качестве аргумента. При передаче но значению объект будет копироваться целиком при каждом вызове функции, что для больших объектов может привести к потере эффективности. Используя параметр-ссылку, функция получает доступ к той области памяти, где размещен сам объект, без создания дополнительной tuff[1000]; }; class Huge { public: double s extern int calc( const Huge & int main() { Huge table[ 1000 ] ; ... инициализация table int sum = 0; for ( int ix=0; ix < 1000; ++ix ) calc () сс1лается на элемент массива типа Huge sum += calc( tab1e[ix] ); копии. Например: Может возникнуть желание использовать нараметр-сс1лку, чтобы избежать создания копии большого объекта, но в то же время не дать вызываемой функции возможности изменять значение аргумента. Если параметр-ссылка не должен модифицироваться внутри функции, то стоит объявить его как ссылку на константу. В такой ситуации class X; extern int foo bar( X& ); int foo( const X& xx ) { ошибка: константа передается функции с параметром неконстантного типа return foo bar( xx ); сигнализирует об ошибке: Для того чтобы программа компилировалась, мы должна: изменить тип параметра extern int foo bar( const X& ); foo bar() . Подойдет любой из следующих двух вариантов: extern int foo bar( X ); передача по значению int foo( const X &xx ) { ... X x2 = xx; создать копию значения foo bar() может поменять x2, xx останется нетронутым return foo bar( x2 ); правильно Вместо этого можно передать копию xx, которую позволено менять: Параметр-ссылка может именовать любой встроенный тип данных. В частности, разрешается объявить параметр как ссылку на указатель, если программист хочет изменить значение самого указателя, а не объекта, который он адресует. Вот пример void ptrswap( int *&vl, int *&v2 ) int *trnp = v2; v2 = vl; vl = tmp; функции, обменивающей друг с другом значения двух указателей: Объявление int *&v1; компилятор способен распознать и пресечь попытку непреднамеренного изменения значения аргумента. В следующем примере нарушается константность параметра xx функции foo() . Поскольку параметр функции foo bar() не является ссылкой на константу, то нет гарантии, что вызов foo bar() не изменит значения аргумента. Компилятор должно читаться справа налево: v1 является ссылкой на указатель на объект типа int. Модифицируем функцию main() , которая вызывала rswap() , для проверки работы #include <iostream> void ptrswap( int *&vl, int *&v2 ); int main() { int i = 10; int j = 20; int *pi = &i; int *pj = &j; cout << Перед ptrswap():\tpi: << *pi << \tpj: << *pj << endl; ptrswap( pi, pj ); cout << После ptrswap():\tpi: << *pi << \tpj: << pj << endl; return 0; ptrswap() : Вот результат работы программы: Перед ptrswap(): pi: 10 pj: 20 После ptrswap(): pi: 20 pj: 10 7.3.2. Параметры-ссылки и параметры-указатели Когда же лучше использовать параметры-ссылки, а когда - параметры-указатели? В конце концов, и те и другие позволяют функции модифицировать объекты, эффективно передавать в функцию большие объекты тина класса. Что выбрать: объявить параметр ссылкой или указателем? Как было сказано в разделе 3.6, ссылка может быть один раз инициализирована значением объекта, и впоследствии изменить ее нельзя. Указатель же в течение своей жизни способен адресовать разные объекты или не адресовать вообще. Поскольку указатель может содержать, а может и не содержать адрес какого-либо class X; void manip( X *px ) { проверим на 0 перед использованием if ( px != 0 ) обратимся к объекту по адресу... объекта, перед его использованием функция должна проверить, не равен ли он нулю:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |