在C&#x2B+?

在C&#x2B+?

夜司空 发布于 2021-10-13 字数 92 浏览 854 回复 8 原文

在什么情况下,你希望在C++中使用多个间接(也就是说,在 Foo ** 中的一系列指针)?

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

为你鎻心 2021-10-16 8 楼

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

ErrorCode AllocateObject (void **object);

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

*object = new Object;

这在Win32中的COM编程中经常使用。
这是一个C的事情,在C++中,你可以经常把这个系统封装成一个类,使代码更可读。

伪装你 2021-10-16 7 楼

在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);
居里长安 2021-10-16 6 楼

卡尔:你的例子应该是:

*p = x;

(你有两颗星。):-)

甜扑 2021-10-16 5 楼

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

爱你是孤单的心事 2021-10-16 4 楼

如果将指针作为输出参数传入,则可能希望将其作为 Foo** 传递,并将其值设置为 *ppFoo = pSomeOtherFoo
从算法和数据结构部门,您可以使用双间接更新指针,这比交换实际对象更快。

终止放荡 2021-10-16 3 楼

一种常见的情况是,需要将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关键字简单地返回新创建的实例,但这并不总是合适的-可能函数需要返回其他内容。

只为守护你 2021-10-15 2 楼

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

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

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

可以使用双指针创建多维交错数组:

int ** array = new *int[2];
array[0] = new int[2];
array[1] = new int[3];
悲喜皆因你 2021-10-15 1 楼

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