سؤال

أود التحقق من نوع Superclass A ضد نوع الفئة الفرعية B (مع طريقة داخل superclass A, ، لهذا السبب B سوف يرثها).

إليك ما اعتقدت فعلت خدعة (أي استخدام إعلان الأمام):

#include <iostream>
#include <typeinfo>

using namespace std;

class B;

class A {
  public:
    int i_;
    void Check () {
      if (typeid (*this) == typeid (B))
        cout << "True: Same type as B." << endl;
      else
        cout << "False: Not the same type as B." << endl;
    }
};

class B : public A {
  public:
    double d_;
};


int main () {

  A a;
  B b;

  a.Check (); // should be false
  b.Check (); // should be true

  return 0;
}

لكن هذا الرمز لا يترجم. الخطأ الذي أحصل عليه هو:

main.cc: In member function ‘void A::Check()’:
main.cc:12: error: invalid use of incomplete type ‘struct B’
main.cc:6: error: forward declaration of ‘struct B’

كيف يمكنني حل هذه المشكلة؟

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

المحلول

أعتقد أن المشكلة التي تحاول حلها يتم التعامل معها بشكل أفضل بكثير من خلال طريقة افتراضية:

class A
{
    public:
        virtual bool Check() { return false; };
}


class B : public A
{
    public:
        // override A::Check()
        virtual bool Check() { return true; };
}

يجب ألا يحتاج الأساليب الموجودة في الفئة الأساسية إلى معرفة ما إذا كان الكائن هو "حقا" A أو A B. هذا انتهاك لمبادئ التصميم الأساسية الموجهة نحو الكائنات. إذا كان السلوك يحتاج إلى تغيير عندما يكون الكائن A ب، فيجب تعريف هذا السلوك في B ومعالجته بواسطة مكالمات الأسلوب الظاهري.

نصائح أخرى

ما عليك سوى نقل تعريف الشيك () خارج الجسم من:

#include <iostream>
#include <typeinfo>

using namespace std;

class B;

class A {
  public:
    int i_;
    void Check ();
};

class B : public A {
  public:
    double d_;
};

void A::Check () {
  if (typeid (*this) == typeid (B))
    cout << "True: Same type as B." << endl;
  else
    cout << "False: Not the same type as B." << endl;
}

int main () {

  A a;
  B b;

  a.Check (); // should be false
  b.Check (); // should be true

  return 0;
}

طريقة واحدة ستكون لسحب تعريف Check خارج تعريف الصف، بحيث B يتم تعريف عندما يحصل التحويل البرمجي على تعريف الوظيفة.

class A {
    //...
    void Check();
    //...
};
class B { /* ... */ };

void A::Check() {
    //...
}

انقل التعريف الخاص بك للتحقق أدناه إعلان الفئة B.

ما عليك سوى نقل جسم الوظيفة بعد إعلان B.

#include <iostream>
#include <typeinfo>

struct A
{
    int i_;
    void Check();
};

struct B :  A
{
    double d_;
};

void A::Check()
{
    using namespace std;
    if (typeid (*this) == typeid (B))
    {
        cout << "True: Same type as B." << endl;
    }
    else
    {
        cout << "False: Not the same type as B." << endl;
    }
}

int main()
{
    A a;
    B b;

    a.Check(); // should be false
    b.Check(); // should be true

    return 0;
}

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

ومع ذلك، ما زلت لا أفهم لماذا تريد إجراء مثل هذا الاختبار O_O؟ وكما قال كاداكر هذه ليست ممارسات جيدة

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