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

Я пишу функцию для загрузки текста из файла кода шейдера. Я наткнулся на что-то странное в отношении указателей, и я не могу понять, почему.

У меня есть функция с именем Load. В этой функции я копирую текст, взятый из файлового потока, в выход переменная.

static void Load(const GLchar* source_path,  GLchar* output,GLint& count )
{
string code;

// loading logic here
code= vShaderStream.str(); // copying the string from the stream
count = code.length();
output = new GLchar[count];
std::size_t length = code.copy(output, count, 0);
output[length]= '\0';
}

нагрузка называется так:

for (size_t i = 0; i < d_n_fragment; i++)
{
Load(d_fragment_source_path, d_fragment_code[i], d_fragment_string_count[i]);
}

где d_fragment_code является двойным указателем Glchar **, который уже инициализирован. После загрузки функция вызывается указателем d_fragment_code [я] не содержит текста Я попытался изменить сигнатуру функции загрузки на:

static void Load(const GLchar* source_path,  GLchar*& output,GLint& count )

и, таким образом, передавая указатель по ссылке. Работает после вызова функции d_fragment_code правильно хранит текст, загруженный из файла, но я не понимаю, почему указатель должен передаваться по ссылке.

Я подумал, что достаточно только передать указатель, чтобы изменить его содержимое. Я в замешательстве, не могли бы вы пролить свет на это?

-2

Решение

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

Использование двойных указателей также является аналогичным случаем.

Вот более подробная статья:
http://www.codeproject.com/Articles/4894/Pointer-to-Pointer-and-Reference-to-Pointer

4

Другие решения

output = new GLchar[count];

Это меняет то, что output указывает на. Если вы уверены, что output уже указывает на буфер достаточного размера, удалите эту строку.

3

Я подумал, что достаточно только передать указатель, чтобы изменить его содержимое.

Передачи указателя достаточно, чтобы изменить содержимое объекта (на который указывает). Это здорово, и это по сути тот же эффект, что и передача ссылки.

Но ты этого не делаешь. Вы хотите изменить сам указатель.

Подумайте, хотите ли вы передать объект в функцию таким образом, чтобы функция изменила исходный объект. Давайте назовем объект типа T и представим, что у него есть функция-член mutate это как-то меняет (так что нам не нужно приводить реальный пример этого как T изменения):

void foo(T& handle)
{
handle.mutate();
}

void bar(T* handle)
{
handle->mutate();
}

int main()
{
T obj;
foo(obj);
bar(&obj);
}

И то и другое foo а также bar выполнить то же самое, используя ссылку и указатель соответственно.

Теперь мы можем применить эту логику к чему угодно, обмениваясь различными типами для T, Сценарий, который Вы думая о том, передает не указатель объект, указатель, чтобы изменить его:

void bar(int* handle)
{
handle->mutate();
}

int main()
{
int obj;
bar(&obj);
}

Но ситуация, которую вы на самом деле в вызовах для T сам быть указателем, и использовать foo скорее, чем bar, Понятно, что это сбивает с толку!

void foo(GLint*& handle)
{
handle.mutate();
}

int main()
{
GLint* obj;
foo(obj);
}

Если это поможет, вы могли бы также написать:

void bar(GLint** handle)
{
handle->mutate();
}

int main()
{
GLint* obj;
bar(&obj);
}

что эффективно эквивалентно.

(отказ от ответственности: я не инициализировал obj в любом из этих примеров. Вы захотите.)

2
По вопросам рекламы [email protected]