الأسئلة الشائعة: لماذا تعمل Dynamic_cast فقط إذا كان لدى الفصل طريقة افتراضية واحدة على الأقل؟

StackOverflow https://stackoverflow.com/questions/4227328

  •  26-09-2019
  •  | 
  •  

سؤال

هذا لا يجمع في C ++:

class A
{
};

class B : public A
{
};

...

A *a = new B();
B *b = dynamic_cast<B*>(a);
هل كانت مفيدة؟

المحلول

لان dynamic_cast لا يمكن إلا أن تكون الأنواع المتعددة الأشكال ، لذا حدد المعيار.

يمكنك جعل فئة polymoprophic بإضافة أ virtual المدمرة إلى الطبقة الأساسية. في الواقع ، ربما يجب عليك على أي حال (انظر الحاشية). آخر إذا حاولت حذف أ B اعتراض من خلال A مؤشر ، سوف تثير سلوك غير محدد.

class A
{
public:
  virtual ~A() {};
};

وآخرون!

هامش

هناك استثناءات من "القاعدة" حول الحاجة إلى مدمرة افتراضية في أنواع الأشكال.
أحد هذه الاستثناءات هو عند استخدام boost::shared_ptr كما أشار ستيف جيسوب في التعليقات أدناه. لمزيد من المعلومات حول عندما تحتاج إلى مدمرة افتراضية ، اقرأ هذا عشب سوتر مقالة - سلعة.

نصائح أخرى

كما ذكر الآخر: المعيار يقول ذلك.

فلماذا يقول المعيار ذلك؟

لأنه إذا لم يكن النوع متعدد الأشكال ، فقد يكون (أو؟ سؤال إلى المعلمين القياسيين) نوعًا عاديًا. وبالنسبة للأنواع العادية ، هناك العديد من الافتراضات القادمة من توافق C إلى الوراء. أحد هؤلاء هو أن النوع يتكون فقط من أعضائه كما أعلن المطور + بايت المحاذاة اللازمة. لذلك لا يمكن أن يكون هناك أي حقول إضافية (مخفية). لذلك لا توجد وسيلة لتخزين مساحة الذاكرة المحفوظة بواسطة المعلومات التي هي في الحقيقة B.

هذا ممكن فقط عندما يكون متعدد الأشكال كما هو مسموح به لإضافة مثل هذه الأشياء المخفية. (في معظم التطبيقات يتم ذلك عبر VTABLE).

من 5.2.7 (يلقي الديناميكي):

نتيجة التعبير dynamic_cast<T>(v) هو نتيجة تحويل التعبير V إلى كتابة T.

... خطوط متعددة تشير إلى حالات أخرى ...

وإلا فإن v يجب أن يكون مؤشرًا أو lvalue من نوع متعدد الأشكال (10.3).

من 10.3 (وظائف افتراضية):

يسمى الفئة التي تعلن أو ترث وظيفة افتراضية فئة متعددة الأشكال.

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