سؤال

المراجع في C++ هي conveneint بناء التي تسمح لنا تبسيط التالية التعليمات البرمجية C:

f(object *p){
  //do something
}

int main(){
  object* p = (object*) calloc(sizeof(object));
  f(p);
}

إلى

f(object& o){
  //do something
}

int main(){
  object o = object();
  f(o);
}

مشترك مؤشرات أخرى الراحة في C++ التي تبسط إدارة الذاكرة.ومع ذلك, أنا لست متأكدا من كيفية تمرير shared_ptr إلى وظيفة مثل f(object& o) الذي يقبل الحجج من قبل مرجع ؟

f(object& o){
  //do something
}

int main(){
  shared_ptr<object> p (new object());
  f(*p);
}

سوف المشتركة المؤشر عندما تكون زيادة موضوعه مرت الإشارة إلى وظيفة ؟

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

المحلول

ونلقي shared_ptr من حيث القيمة، وسوف تزيد عدد مرجع. هذا هو أسهل عند typedef ما يلي:

typedef boost:shared_ptr<object> object_ptr;

void foo(object_ptr obj)
{
    obj->/* stuff*/;
    obj.reset(); //only resets this local copy, that means:
                 // reduce reference count (back to 1), and
                 // set obj to point at null.
}

int main(void)
{
    object_ptr obj(new object());
    foo(obj);
}

ونضع في الاعتبار الإشارات هي أسماء مستعارة. عند تمرير بالرجوع، وكنت لا يمر المؤشرات، نسخ، الخ ...، كنت التعرج كائن آخر. (في الواقع يتم تنفيذها على أنها مؤشرات):

typedef boost:shared_ptr<object> object_ptr;

void foo(object_ptr& obj)
{
    obj.reset(); // the references was never increased, since a copy has not
                 // been made, this *is* obj in main. so the reference 
                 // goes to 0, and obj is deleted
}

int main(void)
{
    object_ptr obj(new object);
    foo(obj); // after this, obj has been reset!
}

وتذكر دائما أن const صحيحة، لمنع الأخطاء:

typedef boost:shared_ptr<object> object_ptr;

void foo(const object_ptr& obj)
{
    obj.reset(); // cannot do! 
}

int main(void)
{
    object_ptr obj(new object);
    foo(obj);
}

وأعتقد أن عليك أن تفضل لتمرير مؤشرات الذكية كمراجع عندما يكون ذلك ممكنا، لتجنب الزيادات الغريبة والتناقصات (ونسخ وغيرها).

نصائح أخرى

<اقتباس فقرة>   

هل يمكن زيادة مؤشر المشتركة عندما يتم تمرير هدفها بالرجوع إلى وظيفة؟

لا، كما يمكنك الوصول إلى مؤشر الخام ومن ثم تمريرها. تريد أن تفعل شيئا مشابها لهذا:

f(shared_ptr<object> o){
  //do something
}

int main(){
  shared_ptr<object> p (new object());
  f(p);
}
f(object& o){
  //do something
}

int main(){
  shared_ptr<object> p (new object());
  f(*p);
}

سوف المشتركة المؤشر تكون زيادة عندما موضوعه مرت الإشارة إلى وظيفة ؟

في الكود أعلاه - لا. p سوف يكون لها مرجعية العداد يساوي 1 في جميع الأوقات.يمكنك التحقق من هذا في مصحح أخطاء.shared_ptr إشارة العداد بحساب عدد shared_ptr الحالات التي تشير إلى نفس الكائن, لا تتبع المراجع إنشاء طريق استدعاء المشغل* ().و لا يجب أن - منذ p يضمن أن يعيش حتى نهاية نطاق استدعاء دالة في نفس النطاق (أو أكثر) p سوف يكون هناك طوال المكالمة f().لذلك كل شيء على ما يرام.

...ما لم يكن في f كنت تأخذ عنوان o وتخزينها في مكان ما أنه سوف تستمر بعد f العوائد.هذا يجب تجنبه بكل الوسائل - تمرير shared_ptr إذا كنت في حاجة للقيام بذلك.

وأول الأشياء أولا، من وجهة نظر وظائف للعرض، المراجع في C ++ هي بالضبط نفس المؤشرات. كان هم السبب في أنها أضيفت إلى اللغة فقط لجعل جملة من الحمولة الزائدة المشغل أن يكون أكثر طبيعية. (على سبيل المثال السماح لأحد لكتابة + ب بدلا من وو+ وب)

ولديك C و C ++ نماذج التعليمات البرمجية على الاطلاق لا تعادل. ان النسخة C ++ C من التعليمات البرمجية الخاصة بك على النحو التالي:

f(object *p){
  //do something
}

int main(){
  object o;
  object_constructor(&o);
  f(&o);
  object_destructor(&o);
}

في الواقع، وهذا هو نوع من التعليمات البرمجية التي مترجم C ++ الخاص بك وسوف تولد من الناحية النظرية.

وفيما يتعلق بسؤالك الثاني: نعم، هذا هو الطريق الصحيح لاستدعاء الدالة و. لن تكون زيادة العداد مؤشر المشتركة. سيتم تمرير المؤشر الفعلي للكائن، كما لو كنت لا تستخدم shared_ptr. فمن آمن ولكن، طالما و لا تفعل أي شيء غير تقليدي. فقط تذكر أن نفس الشيء بالضبط ما يحدث كما لو أخذت المعلمة و في مؤشر بدلا من مرجع. الفرق الوحيد هو أن المترجم يمر التلقائى عنوان المتغير دون الحاجة إلى استخدام صراحة المشغل و.

وأنا شخصيا لا أحب أن يمر أي وقت مضى المتغيرات بالرجوع (يمر بالرجوع CONST على ما يرام على الرغم من). أنا أفضل أن استخدام مؤشر بدلا من ذلك لأنه يجعل من أكثر وضوحا في موقع الدعوة التي وظيفة أننا يدعو يحتمل أن تكون قد تعديله في حجة (منذ ورمزا مرئيا في الموقع الاتصال).

والسلام

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