Вопрос прост и, возможно, обсуждался ранее, но я мог найти четкий ответ для своего случая. Предположим, я передаю объект-указатель в функцию
#include "foo.h"int main()
{
foo * aFoo = new foo;
bar(aFoo);
delete aFoo;
aFoo = NULL;
return 0;
}
Тогда функция написана так
void bar (foo *f)
{
f->insert();
}
Вопрос:
Это call by value
или же call by reference
? Я знаю, что в вызове по значению есть издержки для копирования объекта из main () в bar (). Так что я хочу быть уверен, что это call by reference
,
Это вызов по значению, где значение указателя aFoo
копируется в параметр функции f
,
Вызов по ссылке это вызов, где параметр является ссылкой, и побочные эффекты на аргумент (а не на объектах, на которые, возможно, указывает этот аргумент), которые встречаются внутри функции, видимы для вызывающей стороны, когда функция возвращается.
Так, например, это функция, принимающая параметр по ссылке:
void bar(foo*& f)
// ^
// Here you are taking a pointer by reference
Пока это функция, принимающая параметр по значению:
void bar(foo* f)
// ^
// Here you are taking a pointer to foo by value
Вы, вероятно, озадачены тем, что принимая foo
по ссылке и написанию:
void bar(foo& f)
{
f.insert();
}
Имеет почти такой же эффект, как прохождение указатель к тому же foo
объект по значению и записи:
void bar(foo* f)
{ // Precondition: f != nullptr
f->insert();
}
Тем не менее, две вещи концептуально разные. Хотя значение / состояние объекта, который вы передали в первом случае, может отличаться, когда функция возвращается из значения / состояния, которое она имела до вызова функции, во втором случае значение указателя Вы предоставили, будет таким же, как было до того, как вы bar()
— пока объект указал на возможно, претерпел некоторые изменения состояния.
Также обратите внимание, что указатель может быть нулевым, а ссылка всегда связана с объектом.
В вашем случае это call by value
с точки зрения указателя на Фу формально. Но так как вы передаете указатель на функцию вместо самого экземпляра класса, то это концептуально вызов по ссылке в терминах экземпляра класса, поскольку вызов функции копирует не весь экземпляр, а только его указатель.
Foo fooInstance;
// providing a way to point (less formally you can call it refer) to the instance
Foo* fooPointer = &fooInstance;
// this function call is call by value (passing the value of the pointer).
// but you can logically view it as 'call by reference' to fooInstance.
bar(fooPointer);