在C ++中使用多个间接是什么用途?

时间:2008-09-16 10:41:22

标签: c++ pointers

在什么情况下你可能想在C ++中使用多个间接(即Foo **中的指针链)?

8 个答案:

答案 0 :(得分:12)

@aku指出的最常见的用法是允许在函数返回后更改指针参数。

#include <iostream>

using namespace std;

struct Foo {
    int a;
};

void CreateFoo(Foo** p) {
    *p = new Foo();
    (*p)->a = 12;
}

int main(int argc, char* argv[])
{
    Foo* p = NULL;
    CreateFoo(&p);
    cout << p->a << endl;
    delete p;
    return 0;
}

这将打印

12

但是在下面的示例中还有其他一些有用的用法,用于迭代字符串数组并将它们打印到标准输出。

#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    const char* words[] = { "first", "second", NULL };
    for (const char** p = words; *p != NULL; ++p) {
        cout << *p << endl;
    }

    return 0;
}

答案 1 :(得分:7)

IMO最常见的用法是传递对指针变量的引用

void test(int ** var)
{
 ...
}

int *foo = ...
test(&foo);

您可以使用双指针创建多维锯齿状数组:

int ** array = new *int[2];
array[0] = new int[2];
array[1] = new int[3];

答案 2 :(得分:5)

一种常见的情况是,您需要将 null 指针传递给函数,并在该函数内初始化,并在函数外部使用。没有multplie间接,调用函数永远不会访问初始化对象。

考虑以下功能:

initialize(foo* my_foo)
{
    my_foo = new Foo();
}

任何调用'initialize(foo *)'的函数都无法访问 Foo 的初始化实例,因为传递给此函数的指针是副本。 (毕竟,指针只是一个整数,整数按值传递。)

但是,如果函数定义如下:

initialize(foo** my_foo)
{
    *my_foo = new Foo();
}

......它被这样称呼......

Foo* my_foo;

initialize(&my_foo);

...然后调用者可以通过'my_foo'访问初始化的实例 - 因为它是传递给'initialize'的指针的地址

当然,在我的简化示例中,'initialize'函数可以通过return关键字返回新创建的实例,但这并不总是适合 - 也许函数需要返回其他内容。

答案 3 :(得分:3)

如果您将指针作为输出参数传递,则可能希望将其作为Foo**传递,并将其值设置为*ppFoo = pSomeOtherFoo

从算法和数据结构部门,您可以使用双重间接更新指针,这可能比交换实际对象更快。

答案 4 :(得分:1)

一个简单的例子是使用int** foo_mat作为2d整数数组。 或者您也可以使用指针指针 - 假设您有一个指针void* foo,并且您有2个不同的对象,这些对象具有以下成员的引用:void** foo_pointer1void** foo_pointer2,通过指向指针,您可以实际检查*foo_pointer1 == NULL是否指示foo为NULL。如果foo_pointer1是常规指针,您将无法检查foo是否为NULL。 我希望我的解释不会太乱:)

答案 5 :(得分:1)

通常当您将指向函数的指针作为返回值传递时:

ErrorCode AllocateObject (void **object);

其中函数返回成功/失败错误代码,并使用指向新对象的指针填充object参数:

*object = new Object;

在Win32中的COM编程中使用了很多。

这更像是一件C事情,在C ++中,你经常可以将这种类型的系统包装成一个类,以使代码更具可读性。

答案 6 :(得分:1)

卡尔:你的榜样应该是:

*p = x;

(你有两颗星。): - )

答案 7 :(得分:1)

在C中,绝对需要成语。考虑一下您希望函数将字符串(纯C,即char *)添加到char *指针数组的问题。函数原型需要三个间接级别:

int AddStringToList(unsigned int *count_ptr, char ***list_ptr, const char *string_to_add);

我们称之为:

unsigned int   the_count = 0;
char         **the_list  = NULL;

AddStringToList(&the_count, &the_list, "The string I'm adding");

在C ++中,我们可以选择使用引用,这将产生不同的签名。但是我们仍然需要你在原始问题中提到的两个间接层面:

int AddStringToList(unsigned int &count_ptr, char **&list_ptr, const char *string_to_add);