【问题标题】:Why in C++ do I need to pass a pointer by reference to change the pointed content?为什么在 C++ 中我需要通过引用传递一个指针来更改指向的内容?
【发布时间】:2015-01-30 13:00:13
【问题描述】:

我正在编写一个函数来从着色器代码文件中加载文本。我偶然发现了关于指针的一些奇怪的东西,我不知道为什么。

我有一个名为 Load 的函数。在这个函数中,我将文本从文件流中复制到 output 变量中。

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是这样调用的:

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** 的双指针,已经初始化。调用 Load 函数后,指针 d_fragment_code[i] 不包含任何文本。我尝试将 Load 函数的签名更改为:

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

从而通过引用传递指针。它可以工作,在调用函数后 d_fragment_code 正确保存了从文件加载的文本,但我不明白为什么要通过引用传递指针。

我认为只传递一个指针就足以改变它的内容。我很困惑,你能解释一下吗?

【问题讨论】:

  • 你不只是改变内容,你在这里改变指针:output = new GLchar[count];

标签: c++ pointers double-pointer


【解决方案1】:

如果你必须修改指针而不是指针指向的对象,你应该通过引用传递指针。

使用双指针也是类似的情况。

这里有更详细的文章:
http://www.codeproject.com/Articles/4894/Pointer-to-Pointer-and-Reference-to-Pointer

【讨论】:

    【解决方案2】:
    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);
    }
    

    foobar 完成同样的事情,分别使用引用和指针。

    现在我们可以通过将各种类型交换为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。你会想要的。)

    【讨论】:

    • 您可能想指出 哪里 OP 实际上正在更改指针本身。他们似乎不知道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多