سؤال

إذا كان لدي الفصول التالية:

class A
{
    ...
}

class B
{
    ...
}

class C : public A, public B
{
    ...
}

وفي مكان ما اكتشفت أن مؤشر الفصل B أن لدي بالفعل يشير إلى الفصل C, ، لكن الوظيفة تتطلب مؤشرًا إلى الفصل A, ، ماذا يمكنني أن أفعل للحصول على هذا المؤشر إلى الفصل A?

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

المحلول

إذا كنت تعرف بالتأكيد أن لديك ملف B* هذا يشير إلى أ C كائن ، يمكنك استخدام زوج من static_castس:

B* bp = new C();
C* cp = static_cast<C*>(bp);
A* ap = static_cast<A*>(cp);

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

B* bp = new C();
A* ap = dynamic_cast<A*>(bp);

dynamic_cast لديه فائدة إضافية إذا فشلت (أي ، إذا bp لا يشير في الواقع إلى C) ، يعود فارغة. لها عيب تكلفة الأداء الطفيفة (static_cast مجاني فعليًا في وقت التشغيل).

نصائح أخرى

الرمز

class A
{
};
class B
{
};
class C : public A, public B
{
};
int main() {
  C c;
  A *a = &c;
}

صالح لأن C هو بالفعل A ، وبالتالي فإن المهمة صالحة.

إذا وراثة C من A كما أظهرت ، فيجب أن يكون مؤشر C* قابلاً للتحويل ضمنيًا إلى مؤشر*. هل من الممكن أنك لم تتضمن إعلان الفئة C ، بحيث لا يكون المترجم على دراية بعلاقة الميراث هذه؟ أو أن هناك في الواقع علاقة ميراث مختلفة عن تلك الواردة في سؤالك؟ ستكون بعض التعليمات البرمجية مفيدة في تشخيص هذه المشكلة.

يحرر
بناءً على النسخة المحدثة من سؤالك:

// Converts b to type A*, but only if it is actually
// of type C; otherwise, returns NULL
A* convertBtoAviaC(B* b) {
   C* c = dynamic_cast<C*>(b);
   return c; // note may be NULL, if b is not a C
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top