C ++中的多重间接使用有什么用?

时间:2020-03-05 18:55:36  来源:igfitidea点击:

在什么情况下,我们想在C ++中使用多个间接寻址(即,像" Foo **"中那样的一系列指针)?

解决方案

回答

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

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

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

我们可以使用双指针创建多维锯齿形数组:

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

回答

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

并且从算法和数据结构部门,我们可以使用该双重间接更新指针,这比例如交换实际对象要快。

回答

一个简单的例子是将" int ** foo_mat"用作二维整数数组。
或者我们也可以使用指向指针的指针,假设我们有一个指针" void * foo",并且我们有两个不同的对象,该对象使用以下成员对其进行引用:" void ** foo_pointer1"和" void ** foo_pointer2" ,通过使用指向指针的指针,我们实际上可以检查* foo_pointer1 == NULL是否表示foo为NULL。如果foo_pointer1是常规指针,则我们将无法检查foo是否为NULL。
我希望我的解释不会太混乱:)

回答

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

ErrorCode AllocateObject (void **object);

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

*object = new Object;

这在Win32中的COM编程中经常使用。

这更多是C的事情,在C ++中,我们通常可以将这种类型的系统包装到一个类中,以使代码更具可读性。

回答

卡尔:示例应为:

*p = x;

(我们有两颗星。):-)

回答

一种常见的情况是,我们需要将空指针传递给函数,并在函数内对其进行初始化,并在函数外使用。如果没有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关键字返回新创建的实例,但这并不总是适用,也许该函数需要返回其他内容。

回答

@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;
}

回答

在C语言中,绝对需要成语。考虑以下问题:我们希望函数向字符串char *的指针数组添加字符串(纯C,所以为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);