إلى استخدام ما هو متعددة المراوغة في C++?
سؤال
تحت أي ظرف من الظروف التي قد ترغب في استخدام متعددة المراوغة (التي هي سلسلة من المؤشرات كما في 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++ يمكنك في كثير من الأحيان التفاف هذا النوع من النظام في فئة لجعل رمز أكثر قابلية للقراءة.