إلى استخدام ما هو متعددة المراوغة في C++?

StackOverflow https://stackoverflow.com/questions/71108

  •  09-06-2019
  •  | 
  •  

سؤال

تحت أي ظرف من الظروف التي قد ترغب في استخدام متعددة المراوغة (التي هي سلسلة من المؤشرات كما في Foo **) في C++?

هل كانت مفيدة؟

المحلول

الاستخدام الأكثر شيوعا كما @أكو وأشار إلى أن تسمح تغيير على مؤشر المعلمة أن تكون واضحة بعد ترجع الدالة.

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

نصائح أخرى

المنظمة البحرية الدولية الأكثر شيوعا في الاستخدام هو لتمرير إشارة إلى مؤشر متغير

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

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

يمكنك إنشاء الأبعاد خشنة المصفوفة باستخدام مزدوج المؤشرات:

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

أحد السيناريوهات الشائعة التي تحتاج إلى تمرير null مؤشر على وظيفة ، ويكون ذلك تهيئة ضمن تلك الوظيفة ، و تستخدم خارج الدالة.دون multplie المراوغة ، فإن وظيفة الدعوة لن يكون الوصول إلى تهيئة كائن.

نعتبر الدالة التالية:

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

أي وظيفة المكالمات تهيئة(فو*)' سوف لا يكون لديك الوصول إلى تهيئة مثيل فو, نتيجة المؤشر التي مرت على هذه الوظيفة هو نسخة.(المؤشر هو فقط عدد صحيح بعد كل شيء ، الصحيحه يتم تمريرها حسب القيمة.)

ومع ذلك ، إذا تم تعريف الدالة مثل هذا:

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

و كان يسمى مثل هذا...

Foo* my_foo;

initialize(&my_foo);

...ثم المتصل الوصول إلى تهيئة سبيل المثال ، عبر 'my_foo' - لأنه عنوان المؤشر الذي تم تمريره إلى تهيئة'.

طبعا في المثال المبسط ، تهيئة وظيفة يمكن ببساطة العودة حديثا سبيل المثال عن طريق عودة الكلمة, ولكن هذا لا تتناسب دائما مع - ربما وظيفة يحتاج إلى العودة شيء آخر.

إذا قمت بتمرير مؤشر في إخراج المعلمة ، قد تريد أن تمر عليه كما Foo** وتعيين قيمته كما *ppFoo = pSomeOtherFoo.

و من الخوارزميات-و-البيانات-هياكل الإدارة ، يمكنك استخدام مزدوج المراوغة لتحديث المؤشرات التي يمكن أن تكون أسرع من مثلا مبادلة الكائنات الفعلية.

مثال بسيط سوف تستخدم int** foo_mat كما 2d مجموعة من الاعداد الصحيحه.أو يمكنك أيضا استخدام المؤشرات إلى مؤشرات - دعنا نقول أن لديك مؤشر void* foo و لديك 2 كائنات مختلفة أن يكون إشارة إلى أنه مع الأعضاء التالية أسماؤهم: void** foo_pointer1 و void** foo_pointer2, ، من خلال وجود مؤشر إلى مؤشر يمكنك فعلا تحقق ما إذا كان *foo_pointer1 == NULL مما يدل على أن فو باطل.أنت لن تكون قادرة على التحقق ما إذا كان فو باطل إذا foo_pointer1 العادية المؤشر.أتمنى أن شرحي لم يكن فوضوي للغاية :)

كارل:المثال الخاص بك يجب أن تكون:

*p = x;

(لديك اثنين من النجوم....) :-)

في C, لغة هو المطلوب تماما.النظر في المشكلة التي تريد وظيفة لإضافة سلسلة (نقية ج ، لذلك شار *) إلى مجموعة من المؤشرات إلى شار *.وظيفة النموذج يتطلب ثلاثة مستويات من المراوغة:

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);

عادة عند تمرير مؤشر إلى الدالة قيمة الإرجاع:

ErrorCode AllocateObject (void **object);

حيث ترجع الدالة على النجاح/الفشل رمز الخطأ و يملأ وجوه المعلمة مع مؤشر إلى كائن جديد:

*object = new Object;

يستخدم هذا الكثير في COM البرمجة في Win32.

هذا هو أكثر من C ، C++ يمكنك في كثير من الأحيان التفاف هذا النوع من النظام في فئة لجعل رمز أكثر قابلية للقراءة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top