سؤال

إذا كان لدي فئة على النحو التالي

   class Example_Class 
   {
       private:
         int x; 
         int y; 
       public: 
         Example_Class() 
         { 
             x = 8;
             y = 9;
         }
       ~Example_Class() 
       { } 
   };

والهيكل على النحو التالي

struct
{
   int x;
   int y;
} example_struct;

هو الهيكل في ذكرى example_struct مماثلة لذلك في Example_Class

على سبيل المثال إذا قمت بما يلي

struct example_struct foo_struct;
Example_Class foo_class = Example_Class();

memcpy(&foo_struct, &foo_class, sizeof(foo_struct));

سوف foo_struct.x = 8 و foo_struct.y = 9 (أي:نفس قيم قيم x وy في foo_class)؟

سبب سؤالي هو أن لدي مكتبة C++ (لا أريد تغييرها) تشارك كائنًا برمز C وأريد استخدام بنية لتمثيل الكائن القادم من مكتبة C++.أنا مهتم فقط بخصائص الكائن.

أعلم أن الوضع المثالي هو أن يكون لدى example_class التفاف حول بنية مشتركة بين كود C وC++ ولكن لن يكون من السهل تغيير مكتبة C++ المستخدمة.

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

المحلول

معيار C++ ضمانات أن تخطيطات الذاكرة لـ C struct وC++ class (أو struct -- نفس الشيء) ستكون متطابقة، بشرط أن يكون C++ class/struct يناسب معايير الوجود جراب ("بيانات قديمة عادية").إذن ماذا يعني POD؟

الفئة أو البنية هي POD إذا:

  • جميع أعضاء البيانات عامة وهم أنفسهم POD أو أنواع أساسية (ولكن ليس أنواع مرجعية أو مؤشر إلى عضو)، أو صفائف من هذا القبيل
  • لا يحتوي على مُنشئات محددة من قبل المستخدم أو مشغلي التعيين أو المدمرين
  • ليس لديها وظائف افتراضية
  • ليس لديها فئات أساسية

حول "C++-isms" الوحيدة المسموح بها هي وظائف الأعضاء غير الافتراضية والأعضاء الثابتة ووظائف الأعضاء.

نظرًا لأن فصلك يحتوي على منشئ ومدمر، فإنه لا يتحدث رسميًا من نوع POD، وبالتالي فإن الضمان لا يستمر.(على الرغم من أنه، كما ذكر آخرون، من المرجح أن يكون التخطيطان متطابقين عمليًا على أي مترجم تحاول تجربته، طالما لا توجد وظائف افتراضية).

انظر القسم [26.7] من الأسئلة الشائعة حول C++ Lite لمزيد من التفاصيل.

نصائح أخرى

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

هل هيكل في ذكرى simmilar example_struct إلى أنه في Example_Class

لا يضمن السلوك، وتعتمد مترجم.

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

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

لإضافة إلى ما قاله أشخاص آخرين (على سبيل المثال: مترجم محددة، من المرجح أن العمل طالما لم يكن لديك وظائف الظاهرية):

وأود أن أقترح بشدة ASSERT ثابت (الاختيار تجميع الوقت) أن sizeof (Example_class) == sizeof (example_struct) إذا كنت تفعل هذا. انظر BOOST_STATIC_ASSERT، أو ما يعادل مترجم محددة أو العرف البناء. هذا هو الخط الأول للدفاع جيد إذا كان شخص (أو شيء ما، مثل تغيير المترجم) تعديل الفئة لإبطال المباراة. إذا كنت تريد فحص إضافي، يمكنك أيضا وقت التشغيل تأكد من أن إزاحة إلى أعضاء هي نفسها، والتي (جنبا إلى جنب مع ASSERT حجم ثابت) تضمن صحتها.

في الأيام الأولى من المجمعين C ++ هناك أمثلة عندما كلمات المترجم التغييرات الأولى لبنية مع الطبقة ومن ثم يجمع. الكثير عن أوجه التشابه.

والاختلافات تأتي من الميراث الطبقة، وخاصة، وظائف افتراضية. إذا الفئة تحتوي الدالات الظاهرية، فإنه يجب أن يكون مؤشر لكتابة واصف في بداية تخطيطه. أيضا، إذا يرث الفئة B من الفئة A، ثم تخطيط فئة A تأتي في المقام الاول، تليها تخطيط الفئة B الخاصة.

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

وهنا هو مقال مما يدل على ان ليس هناك حاجة إلى القيام بالكثير لخطوة من الهياكل C إلى C ++ فئات: <لأ href = "http://www.sysexpand.com/؟path=ooplessons/lesson01" يختلط = "نوفولو"> الدرس 1 - من بنية إلى الدرجة

وهنا هو المقال الذي يشرح كيف الجدول وظائف افتراضية يتم تقديمها إلى الفئات التي لها وظائف افتراضية: <لأ href = "http://www.sysexpand.com/؟path=ooplessons/lesson04" يختلط = "نوفولو" > الدرس 4 - تعدد الأشكال

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

وليس هناك شيء يمنعك من استخدام كل نزوة C ++ الميزات في البنية:

struct ReallyAClass
{
    ReallyAClass();
    virtual !ReallAClass();

    /// etc etc etc
};

لماذا لا تخصص صراحة أعضاء الطبقة في البنية عندما تريد تمرير البيانات إلى C؟ بهذه الطريقة يمكنك أن تعرف والتعليمات البرمجية العمل في أي مكان.

من المحتمل أنك تستمد الفصل من البنية، سواء بشكل عام أو خاص.ثم سيتم حل عملية الإرسال بشكل صحيح في كود C++.

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