سؤال

أنا باستخدام مكتبة 3rd الطرف أن الإعلان عن مثل هذا:

typedef struct {} __INTERNAL_DATA, *HandleType;

وأود أن إنشاء فئة يأخذ HandleType في منشئ:

class Foo
{
    Foo(HandleType h);
}

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

struct *HandleType;

ولكن الذي يقول "من المتوقع معرف من قبل *" في دول مجلس التعاون الخليجي.الحل الوحيد الذي أراه هو أن تكتب صفي مثل هذا:

struct __INTERNAL_DATA;
class Foo
{
    Foo(__INTERNAL_DATA *h);
}

ولكن هذا يعتمد على التفاصيل الداخلية من المكتبة.وهذا هو القول ، فإنه يستخدم اسم __الداخلية_البيانات ، وهي تفاصيل التنفيذ.

يبدو أنه ينبغي أن يكون من الممكن إلى الأمام-تعلن HandleType (جزء من الجمهور API) دون استخدام __الداخلية_البيانات (جزء من تنفيذ المكتبة.) أحد يعرف كيف ؟

تحرير:إضافة المزيد من التفاصيل حول ما أبحث عنه.

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

المحلول

تحديث:

أنا استخدامه في التنفيذ .cpp من فو ، ولكن أريد أن تجنب بما في ذلك في بلدي الرأس .ح فو.ربما أنا أيضا ومتحذلق ؟ :)

نعم أنت :) المضي قدما إلى الأمام الإعلان.

إذا HandleType هو جزء من واجهة يجب أن يكون هناك رأس معلنا أن.استخدام رأس.

المشكلة لا تزال غامضة واحد.أنت تحاول حماية ضد شيء لا يمكن.

يمكنك إضافة السطر التالي إلى العميل الخاص بك مكتبة:

typedef struct INTERNAL_DATA *HandleType;

ولكن إذا كان الاسم/هيكل التغييرات قد تكون في بعض الصب قبح.

محاولة قوالب:

template <class T>
class Foo
{
    Foo(T h);
};

إلى الأمام الإعلان على ما يرام.إذا كنت تنوي استخدام مؤشرات أو إشارات تحتاج فقط فئة (__INTERNAL_DATA) الإعلان في نطاق.ومع ذلك ، إذا كنت تنوي استخدام وظيفة عضو أو كائن سوف تحتاج إلى تضمين الرأس.

نصائح أخرى

إذا كان النوع في مكتبة 3rd الطرف ثم فائدة كبيرة إلى الأمام إعلان (عزل يعيد بسبب التغيرات في رؤوس) هو فعال المفقودة.

إذا كنت قلقا بشأن تجميع مرات (وهو كبير الرأس) ثم ربما يمكنك وضعه في رأس precompiled أو مجرد تشمل الرأس ذات الصلة من المكتبة.

E. g.العديد من مكتبة رؤوس تبدو

// library.h
#include "Library/Something.h"
#include "Library/SomethingElse.h"
 typedef struct {} __INTERNAL_DATA, *HandleType;

إذا تم تعريف مثل أن (كل على سطر واحد) ، ثم __البيانات الداخلية بقدر ما هو جزء من واجهة عامة كما HandleType.

ومع ذلك, لا أعتقد __INTERNAL_DATA موجود في الواقع.أكثر من المحتمل ، HandleType حقا (داخليا) int.هذا الغريب التعريف هو مجرد وسيلة لتحديد بحيث انها نفس حجم int, ولكن متميزة ، بحيث مترجم تعطيك رسالة خطأ إذا حاولت اجتياز الباحث حيث كنت من المفترض أن تمر HandleType.مكتبة المورد يمكن بسهولة مثلما حددت على أنها "الباحث" أو "الفراغ*" ، ولكن بهذه الطريقة يمكننا الحصول على بعض نوع التحقق.

ومن ثم __INTERNAL_DATA هو مجرد الاتفاقية لن تتغير.


تحديث:ما سبق كان قليلا من العقلية تجشؤ...حسنا ، __INTERNAL_DATA بالتأكيد لا وجود لها.نحن نعرف هذه الحقيقة لأننا لا نستطيع انظر إنه تعريف فارغة البنية.أنا أعتقد أن الطرف 3rd-مكتبة يستخدم "ج" الخارجية الربط (لا يوجد اسم managling) ، في هذه الحالة ، مجرد نسخ الرموز المميزة ل typedef -- وسوف يكون على ما يرام.

داخل المكتبة نفسها ، HandleType سوف مختلفة تماما التعريف ؛ ربما int, ربما "البنية MyStruct {.......} *".

إذا كنت حقا لا تريد أن تعرض _INTERNAL_DATA إلى المتصل ثم الخاص بك الحقيقي الوحيد في الاختيار هو استخدام الرموز المميزة ل typedef الفراغ* HandleType;ثم داخل المكتبة الخاصة بك يمكنك أن تفعل أي شيء تريده بما في ذلك تغيير كامل تنفيذ *HandleType.

مجرد إنشاء وظيفة مساعد للوصول إلى بيانات حقيقية.

inline _INTERNAL_DATA* Impl(HandleType h) {
    return static_cast<_INTERNAL_DATA*>(h);
}

أنا لست متأكدا تماما ما أنت ذاهب ل ، ولكن ما العمل دون بما في ذلك الفعلية رأس الملف:

// foo.h
class Foo
{
    public:
    template<typename T>Foo(T* h) { /* body of constructor */ }
};

فتذكروا, سوف لا يزال لديك الوصول إلى الجمهور أعضاء __INTERNAL_DATA داخل جسم منشئ.

تحرير: كما أشار جيمس كوران ، __INTERNAL_DATA هيكل ليس له أعضاء ، بحيث يمكن استخدامها على النحو الوارد أعلاه, مع أية مشاكل.

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