могу я иметь этот отрывок кода:
C *pa1 = new C(c2);
и я передаю его другой функции:
foo(pa1);
что точно делает я передаю фактический указатель или его копию, заранее спасибо, и может кто-то давать некоторую информацию о, в котором информация о случаях копируется, и в котором я передаю фактический указатель
объявление нечто:
foo(A const *pa)
Предполагая, что foo объявлено как:
void foo(C* p);
вы передаете копию указателя.
Это означает, что если foo сделает вот так:
p = &some_other_object;
то изменение указателя не будет замечено вызывающей стороной.
Это также означает, что мы копируем указатель, а не вещь, на которую указываем. Если foo сделает это:
p->bar = "Smurf!"
pa1 в вызывающей программе также увидит изменение. По этой причине указатели часто используются для реализации своего рода передачи по ссылке.
Если бы foo был объявлен:
void foo(C*& p);
то p был бы ссылкой на pa1, и изменения в p привели бы к изменениям в pa1. Исторически это также было реализовано с помощью указателей на указатели:
void foo(C** p);
в этом случае вы вызываете foo вот так:
foo(&pa1);
и foo может сделать что-то вроде:
*p = &some_other_object;
чтобы изменить то, на что указывает pa1.
Поскольку pa1
имеет тип «указатель на C», вы передаете указатель на C функции foo
. Вы не копируете реальный объект.
Чтобы передать объект, вам понадобится foo, чтобы взять объект типа C и разыменовать pa1
при передаче:
void foo(C);
...
foo(*pa1);
Since pa1
- указатель (как вы определили его как C *
), вы передаете указатель на объект C в foo
.
При этом неизвестно, передаете ли вы указатель по значению или по ссылке, не увидев объявления foo
.
C *pa1;
объект типа 'C*' создан на стеке (локальная переменная pa1)
pa1 = new C(c2);
объект типа 'C' создан на куче, его адрес возвращен в переменную 'pa1'
foo(pa1)
Можно сказать "объект типа 'C*' (переменная pa1) передан по значению в функцию foo, функция получает копию указателя",
Но также "объект типа 'C' (этот объект создан на куче) передан по ссылке (через указатель) в функцию foo, копия объекта 'C' не создается".
Для передачи по ссылке (без создания копии объекта) можно использовать либо ссылку на объект в С++, либо указатель на объект. Они ведут себя одинаково при передаче параметров функции, т.е. все 4 строки ниже дают тот же эффект, передавая по ссылке (это const ссылки, удалите ключевое слово const, чтобы иметь возможность постоянно изменять объект функцией foo):
foo(const A *pa) { pa->DoSth(); } /*...*/ foo(some_pointer);
foo(const A *pa) { pa->DoSth(); } /*...*/ foo(&some_reference);
foo(const A &pa) { pa.DoSth(); } /*...*/ foo(*some_pointer);
foo(const A &pa) { pa.DoSth(); } /*...*/ foo(some_reference);