سؤال

في C struct ، أنا مضمون ذلك:

struct Foo { ... };
struct Bar {
  Foo foo;
  ...
}
Bar bar;
assert(&bar == &(bar.foo));

الآن ، في C ++ ، إذا كان لدي:

class Foo { ... };
class Bar: public Foo, public Other crap ... {
  ...
}

Bar bar;
assert(&bar == (Foo*) (&bar)); // is this guaranteed?

إذا كان الأمر كذلك ، هل يمكنك أن تعطيني مرجعًا (مثل "لغة البرمجة C ++ ، صفحة XYZ")؟

شكرًا!

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

المحلول

لا يوجد ضمان. من C ++ 03 Standard (10/3 ، class.dived):

الترتيب الذي يتم فيه تخصيص المشاريع الفرعية للفئة الأساسية في الكائن الأكثر اشتقاقًا (1.8) غير محدد.

نصائح أخرى

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

Bar bar;
assert(&bar == (Foo*) (&bar));

لأن الممثلين يستخدمون static_cast (لكل 5.4) سيتم تحويله &bar بشكل صحيح ، سيتم تحويل المقارنة بين المؤشر إلى القاعدة والمؤشر المشتقة بالمثل.

هذا ، ومع ذلك ، لن يكون مضمونًا:

Bar bar;
void* p1 = &bar;
void* p2 = (Foo*)&bar;
assert(p1 == p2); // not guaranteed

لا أتخيل أنه سيكون ، لا أعرف لماذا يجب أن يكون.

لدي سؤال ذي صلة.

إذا كان لديك ميراث الماس:

class Base(){ virtual void AFunc(){}  };

class A:Base{};
class B:Base{void AFunc(){} }

class Test:A,B{};


Base * b = (Base*)new Test;

b->AFunc();

لنفترض أن بنية الذاكرة هي الأساس: أ: ب: اختبار ،

ملاحظة عند نقطة الاتصال ، يعرف كل المترجم هو عنوان بداية الكائن ، ويتوقع Afunc أن يكون بالنسبة لبداية الكائن B ، هاتان العنوانان لن يكونا متماثلين! فكيف يعمل؟

مثل إذا كان B من النوع B ، فإن العنوانين سيكونان هو نفسه ...

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