سؤال

وفق هذه, void* ليس لديه معلومات RTTI ، وبالتالي يلقي من void* ليس قانونيا وهذا منطقي.

إذا كنت أتذكر بشكل صحيح، dynamic_cast من void* كان يعمل على مجلس التعاون الخليجي.

هل يمكنك توضيح المشكلة من فضلك.

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

المحلول

dynamic_cast يعمل فقط على أنواع الأشكال ، أي فئات تحتوي على وظائف افتراضية.

في مجلس التعاون الخليجي يمكنك dynamic_cast إلى void* لكن لا من:

struct S
{
    virtual ~S() {}
};

int main()
{
    S* p = new S();
    void* v = dynamic_cast<void*>(p);
    S* p1 = dynamic_cast<S*>(v); // gives an error
}

نصائح أخرى

في 5.2.7 - Dynamic cast [expr.dynamic.cast] تقول ذلك ل dynamic_cast<T>(v):

  • إذا T هو نوع المؤشر ، v يجب أن يكون rvalue من المؤشر لإكمال نوع الفصل
  • إذا T هو نوع مرجعي ، v يجب أن يكون lvalue لنوع الفصل الكامل (شكرًا usta للتعليق على هذا المفقود)

...

  • خلاف ذلك، v يجب أن يكون مؤشرًا أو lvalue من نوع متعدد الأشكال

لذلك ، لا ، أ (void*) القيمة غير مسموح.

دعونا نفكر في ما قد يعنيه طلبك: قل أنك حصلت على مؤشر حقًا Derived1*, ، لكن الرمز dynamic_cast-نغ فقط يعلم أنه ملف void*. دعنا نقول أنك تحاول إلقاءها على Derived2*, ، حيث كل من الفئتين المشتقة لها قاعدة مشتركة. بشكل سطحي ، قد تعتقد أن جميع المؤشرات ستشير إلى نفس الشيء Base الكائن ، الذي سيحتوي على مؤشر لجدول الإرسال الظاهري ذي الصلة و RTTI ، لذلك يمكن أن يتم تعليق كل شيء معًا. ولكن ، ضع في اعتبارك أن الفئات المشتقة قد تحتوي على فئات أساسية متعددة ، وبالتالي المطلوبة Base قد لا يكون الكائن الفرعي للفئة هو الذي Derived* - متاح فقط كملف void* - يشير. لن ينجح. الخلاصة: يحتاج المترجم إلى معرفة هذه الأنواع حتى يتمكن من إجراء بعض التعديل على المؤشرات بناءً على الأنواع المعنية.

Derived1* -----> [AnotherBase]
                 [[VDT]Base]    <-- but, need a pointer to start of
                 [extra members]    this sub-object for dynamic_cast

(تتحدث بعض الإجابات عن الحاجة إلى المؤشر الذي يلقي من نوعه من النوع متعدد الأشكال ، ولديه وظائف افتراضية. هذا كل شيء صالح ، ولكن مضللة بعض الشيء. كما ترون أعلاه ، حتى لو كان void* هو بالنسبة لمثل هذا النوع ، فإنه لا يزال يعمل بشكل موثوق بدون معلومات النوع الكامل ، لأن المشكلة الحقيقية هي ذلك void* يُفترض أنه يشير إلى بداية الكائن المشتق ، في حين أنك تحتاج إلى مؤشر إلى كائن فرعي من الفئة الأساسية يستمد منه النوع إلى النوع.)

صحيح ان void* لا يمكن أن يكون dynamically_castإد من.

ربما تكون سوءًا. مع G ++ 4.5 والرمز التالي

struct A {
    virtual ~A();
};

int main() {
    A a;
    void *p = &a;
    A* pa = dynamic_cast<A*>(p);
}

أحصل على الخطأ التالية:

لا يمكن dynamic_cast 'p' (من النوع "void*') لكتابة" الهيكل A*"(المصدر ليس مؤشرًا للفصل)

أعتقد أنك تخلط بين dynamic_cast إلى void*. هذا قانوني ويحصل على المؤشر إلى كائن الطبقة الأكثر اشتقاقًا.

dynamic_cast من void* غير قانوني - النوع الذي تم إلقاؤه من تعدد الأشكال - يحتوي على وظيفة افتراضية واحدة على الأقل (تعداد المدمر الافتراضي أيضًا).

يمكنك إلقاء مؤشر إلى النوع متعدد الأشكال إلى void *, ، ولكن ليس العكس.

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