问题
I am writing a function to load text from shader code file. I have stumbled upon something strange regarding pointers and I cannot figure out why.
I have a function named Load. In this function I copy text, taken from a file stream, in the output variable.
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';
}
Load is called in this way:
for (size_t i = 0; i < d_n_fragment; i++)
{
Load(d_fragment_source_path, d_fragment_code[i], d_fragment_string_count[i]);
}
where d_fragment_code is a double pointer of Glchar** which is already initialized. After Load function is called the pointer d_fragment_code[i] contains no text. I tried to change the signature of the Load function to:
static void Load(const GLchar* source_path, GLchar*& output,GLint& count )
and thus passing the pointer by reference. It works, after the function is called d_fragment_code holds correctly the text loaded from the file but I don't understand why a pointer it is to be passed by reference.
I thought that passing a pointer only would suffice to change its content. I am confused, could you shed some light on it?
回答1:
You should pass pointers by reference if you have to modify the pointer rather than the object that the pointer is pointing to.
Using double pointers is also a similar case.
Here is a more detailed article:
http://www.codeproject.com/Articles/4894/Pointer-to-Pointer-and-Reference-to-Pointer
回答2:
output = new GLchar[count];
This changes what output
points to. If you are sure that output
already points to a buffer of sufficient size, remove this line.
回答3:
I thought that passing a pointer only would suffice to change its content.
Passing a pointer suffices to change the content of the pointee (the thing pointed to). That's great, and it has essentially the same effect as passing a reference.
But you're not doing that. You want to change the pointer itself.
Consider, if you wanted to pass an object into a function such that the function altered the original object. Let's call the object's type T, and let's pretend that it has a member function mutate
that changes it somehow (so that we don't have to give a real-world example of this as T
changes):
void foo(T& handle)
{
handle.mutate();
}
void bar(T* handle)
{
handle->mutate();
}
int main()
{
T obj;
foo(obj);
bar(&obj);
}
Both foo
and bar
accomplish the same thing, using a reference and a pointer respectively.
Now we can apply this logic to anything, by exchanging various types for T
. The scenario that you're thinking of, is passing some non-pointer object, by pointer, to mutate it:
void bar(int* handle)
{
handle->mutate();
}
int main()
{
int obj;
bar(&obj);
}
But the situation you're actually in calls for T
itself to be a pointer, and to use foo
rather than bar
. It's understandable that this is confusing!
void foo(GLint*& handle)
{
handle.mutate();
}
int main()
{
GLint* obj;
foo(obj);
}
If it helps, you could also have written:
void bar(GLint** handle)
{
handle->mutate();
}
int main()
{
GLint* obj;
bar(&obj);
}
which is effectively equivalent.
(disclaimer: I didn't initialise obj
in any of those examples. You'll want to.)
来源:https://stackoverflow.com/questions/28236505/why-in-c-do-i-need-to-pass-a-pointer-by-reference-to-change-the-pointed-conten