سؤال

وكيف هي الكائنات المخزنة في الذاكرة في C ++؟

لفئة العادية مثل

class Object
    {
public:
    int i1;
    int i2;
    char i3;
    int i4;
private:
    };

وباستخدام مؤشر القطعة كصفيف يمكن استخدامها للوصول إلى I1 على النحو التالي؟

((Object*)&myObject)[0] === i1?

وأسئلة أخرى على SO توحي بأن يلقي البنية إلى مؤشر سوف نشير إلى أول عضو لPOD-أنواع. كيف يختلف هذا عن الطبقات مع الصانعين على كل حال؟ أيضا ما هي الطريقة هو مختلف لأنواع غير POD؟

وتحرير:

في الذاكرة وبالتالي سيتم وضع الطبقة المشار إليها أعلاه كما يلي؟

[i1 - 4bytes][i2 - 4bytes][i3 - 1byte][padding - 3bytes][i4 - 4bytes]
هل كانت مفيدة؟

المحلول

وتقريبا. أنت يلقي إلى كائن *، وأهمل في اتخاذ عنوان. دعونا إعادة طرح ما يلي:

((int*)&myObject)[0] == i1

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

ملحوظة انني لن تكون سريعة جدا لاقول لكم انها ستعمل إذا كنت قد سئل عن I3 - في هذه الحالة، حتى بالنسبة للPOD واضحة، والمحاذاة أو endianness يمكن بسهولة المسمار لكم

.

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

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

نصائح أخرى

وضعت فئات بدون أعضاء الظاهري ودون الميراث في الذاكرة تماما مثل البنيات. ولكن، عند البدء في الحصول على مستويات أشياء يمكن الحصول على الميراث صعبة ويمكن أن يكون من الصعب معرفة ما هي الأشياء النظام في الذاكرة (لا سيما وراثة متعددة).

وعندما يكون لديك أعضاء الظاهري، لديهم "vtable" في الذاكرة التي تحتوي على مؤشرات إلى وظيفة الفعلية التي يحصل إنشاؤها على أساس التسلسل الهرمي الميراث الطبقة.

وخلاصة القول هي: عدم الدخول الطبقات بهذه الطريقة على الإطلاق إذا كان يمكنك تجنب ذلك (وأيضا لا memset لهم أو memcpy منهم). إذا كان يجب القيام بذلك (لماذا؟) ثم الحرص على أن تعرف بالضبط كيف كائنات الفئة الخاصة بك سوف تكون في الذاكرة وتوخي الحذر لتجنب الميراث.

وانها الاختلاف في أن هذه الحيلة هي صالحة فقط لأنواع POD. هذا هو حقا كل ما في الامر. يحدد المعيار أن هذا يلقي صالحة لنوع POD، ولكن لا تقدم أي ضمانات حول ما يحدث مع أنواع غير POD.

وانها حقا يتوقف على المترجم، أو بالأحرى، يتم ترك الأمر للمترجم لتحديد تخطيط الذاكرة.

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

والأمور تزداد سوءا مع الميراث الظاهري، حيث يمكن أن layed الفئات الأساسية الموروثة تقريبا من على في أي مكان في الذاكرة المخصصة لذلك المثيل معينة.

وPOD مختلفة لأنه يحتاج لتكون متوافقة مع C.

وعادة ما يهم هو ليس ما إذا كان فئة لديها المنشئ: ما يهم هو ما إذا كانت فئة لديها أية أساليب الظاهري. لمزيد من التفاصيل، وجوجل ل 'vtable "و" vptr ".

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