سؤال

لنفترض أن رأس الملف يحدد وظيفة القالب.الآن لنفترض اثنين تنفيذ الملفات #include هذا الرأس, و كل واحد منهم لديه استدعاء الدالة القالب.سواء في تنفيذ ملفات وظيفة القالب مثيل مع نفس النوع.

// header.hh
template <typename T>
void f(const T& o)
{
    // ...
}

// impl1.cc
#include "header.hh"

void fimpl1()
{
    f(42);
}

// impl2.cc
#include "header.hh"

void fimpl2()
{
    f(24);
}

قد يتوقع رابط يشكو عدة تعاريف f().على وجه التحديد, إذا f() لن تكون قالب ثم من شأنه أن يكون في الواقع القضية.

  • كيف الرابط لا يشكو عدة تعاريف f()?
  • هو محدد في معيار رابط يجب التعامل مع هذا الوضع بشكل مناسب ؟ وبعبارة أخرى, يمكنك دائما الاعتماد على برامج مشابهة فوق تجميع الرابط ؟
  • إذا كان رابط يمكن أن تكون ذكية بما فيه الكفاية إلى إزالة الغموض مجموعة من وظيفة قالب التجسيدات, لماذا لا يمكن أن تفعل الشيء نفسه بالنسبة المهام العادية ، نظرا كانت متطابقة كما هو الحال بالنسبة مثيل وظيفة القوالب ؟
هل كانت مفيدة؟

المحلول

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

يحرر:إيضاح:لا يقارن الرابط محتويات الوظيفة ويحدد أنها متماثلة.يتم وضع علامة على الوظائف المُصممة على هذا النحو ويتعرف الرابط على أن لها نفس التوقيعات.

نصائح أخرى

Gnu C++ compiler دليل وقد مناقشة جيدة من هذا.مقتطف:

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

Borland نموذج

Borland C++ حلها القالب مثيل المشكلة عن طريق إضافة رمز يعادل المشتركة كتل بهم رابط;مترجم تنبعث قالب الحالات في كل ترجمة الوحدة التي يستخدمها ، linker ينهار معا.ميزة هذا النموذج هو أن الرابط فقط أن تنظر في موضوع الملفات أنفسهم ؛ لا يوجد الخارجية تعقيد يدعو للقلق.هذا العيب هو أن تجميع الوقت هو زيادة لأن قالب مدونة ويجري تجميع مرارا وتكرارا.رمز كتب هذا النموذج يميل إلى وتشمل تعاريف جميع القوالب في ملف الرأس ، حيث يجب أن يكون ينظر إلى مثيل.

Cfront نموذج

AT&T C++ مترجم, Cfront, حل قالب مثيل المشكلة من خلال خلق مفهوم قالب مستودع تلقائيا الحفاظ على مكان القالب الحالات التي يتم تخزينها.أكثر حداثة نسخة من مستودع يعمل على النحو التالي:كما الفرد كائن الملفات مبنية, مترجم الأماكن أي قالب التعاريف التجسيدات التي واجهتها في مستودع.في وقت الارتباط الرابط المجمع يضيف في الكائنات في مستودع و يجمع أي حاجة الحالات التي لم تكن سابقا المنبعثة.مزايا هذا النموذج أكثر الأمثل سرعة تجميع ، القدرة على استخدام نظام linker;لتنفيذ Borland نموذج برنامج التحويل البرمجي المورد أيضا يحتاج إلى استبدال رابط.مساوئ هي إلى حد كبير زيادة التعقيد ، وبالتالي احتمال الخطأ ؛ بعض التعليمات البرمجية هذا يمكن أن يكون مجرد شفافة ، ولكن في الممارسة العملية يمكن أن يكون من الصعب جدا لبناء برامج متعددة في واحد دليل برنامج واحد في عدة الدلائل.رمز مكتوب على هذا نموذج يميل إلى تعريفات منفصلة من غير مضمنة الأعضاء في قوالب ملف منفصل ، التي ينبغي أن تكون جمعها بشكل منفصل.

عندما تستخدم مع جنو ld الإصدار 2.8 أو في وقت لاحق على قزم النظام مثل جنو/لينكس أو سولاريس 2 ، أو على Microsoft Windows, G++ يدعم Borland نموذج.على أنظمة أخرى ، G++ تنفذ ولا التلقائي نموذج.

هذه حالة خاصة إلى حد ما بالنسبة للقوالب فقط.

يقوم المترجم فقط بإنشاء مثيلات القالب المستخدمة بالفعل.نظرًا لأنه لا يتحكم في التعليمات البرمجية التي سيتم إنشاؤها من الملفات المصدر الأخرى، فيجب عليه إنشاء رمز القالب مرة واحدة لكل ملف، للتأكد من إنشاء الطريقة على الإطلاق.

نظرًا لأنه من الصعب حل هذه المشكلة (يحتوي المعيار على extern الكلمة الرئيسية للقوالب، لكن g++ لا ينفذها) يقبل الرابط ببساطة التعريفات المتعددة.

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