עבור לתוכן

ירושה ופולימורפיזם: ++C

Featured Replies

פורסם

יש לי בעיה בתכנית שאני יושב עליה יותר מדי זמן, מקווה שתאירו את עיניי.

לא אלאה אתכם בפרטי התכנית, כך שאנסה להתנסח בצורה מופשטת.

בתכנית ישנם (בין היתר) 3 קלאסים: A, B, C.

B יורש מA, ו-C יורש מB.

אציין שקיימים נתונים שונים בA, B, וC, כך שהקלאסים היורשים רק מרחיבים את הקלאסים מהם הם יורשים (ירושה קלאסית).

במהלך התכנית אני כותב את השורה הבאה:

A item = new C

השורה הנ"ל מקבלת גם ארגומנטים שמקבל הקונסטרקטור של C.

טיפוס זמן הריצה של item הינו C, וזמן קומפילציה - A.

הכל מתקמפל ורץ תקין.

בזמן ריצה, כשאני מנסה לבדוק את הנתונים בitem, בעזרת intellisense של הVS, הוא מוצג כאילו הוא מסוג A , ולא C.

כלומר, האובייקט item שאמור להכיל נתונים של אובייקט מסוג C, מכיל רק את הנתונים של האובייקט A.

מה גם שהארגומנטים שקיבל הקונסטרקטור בשורה הנ"ל כאילו נעלמו..

תודה מראש,

גלעד

פורסם

אתה מתכוון לדיבאגר ולא ל-Intellisense (שהוא מנגנון השלמת הקוד). קצת קשה לומר מה הבעיה בלי לראות את הקוד עצמו.

פורסם

ברגע שאתה מבצע

A a = new C();

אז אתה מקבל את a שהוא מטיפוס A אבל מכיל את השדות של C (רק אלה שקיימות גם ב-A).

פורסם
  • מחבר

הקוד די ארוך יחסית (15 קלאסים), אשאל זאת כך:

האם ישנה דרך לגשת לערכי זמן ריצה, בזמן קומפילציה? ללא קאסטינגס למיניהם?

פורסם

גישה ל:

item->m_data כאשר המשתנה m_data הוא משתנה שמוגדר רק בקלאס C היורש מB, שיורש מA.

פורסם

אם item הוא מטיפוס *A, אז אי אפשר לעשות את זה בלי המרה, כי הקומפיילר לא יכול לדעת ש-item מצביע לאובייקט מטיפוס C - לדוגמה, ייתכן שקיימת מחלקה אחרת D שיורשת מ-A ו-item הוא מצביע לאובייקט מטיפוס D, ולא C.

פורסם
  • מחבר

העניין הוא שגם המרה רגילה לא עובדת.

האם הסינטקס אמור להיות כך?

(C *a= dynamic_cast<A*>(item->m_data

פורסם

יותר כמו:

C* c = dynamic_cast<C*>(item);
if (c!=0) ...

פורסם
  • מחבר

יותר כמו:

C* c = dynamic_cast<C*>(item);
if (c!=0) ...

למה התכוונת בארגומנט item? קלאס Base?

פורסם

אתה הגדרת את item... השם של המשתנה מסוג A שמקבל new C

פורסם
  • מחבר

לא מתקמפל.

הכוונה שלי בסופו של דבר היא להכניס ערכים בצורה הבאה:

Item->m_data->moreData

בקיצור, ההמרה לא עובדת.

פורסם

למה שאתה התכוונת במשתנה item.

פורסם
  • מחבר

//Map.cpp

#include "Map.h"

#include "Node.h"

#include "Airplane.h"

using namespace std;

Map::Map()

{

itemHead = NULL;

attackHead = NULL;

defenseHead = NULL;

}

Map::~Map()

{}

void Map::createAirplane(char* buffer, Map *m)

{

char* separator;

separator = strtok(buffer, ",");

separator = strtok(NULL, ",");

Node *airplaneNode = new Node();

airplaneNode->m_data = new Airplane(21); // the value "21" is just for testing

Airplane *c = dynamic_cast<Airplane*>(airplaneNode->m_data)-> // Error: the operand of a runtime dynamic_cast must have a polymorphic class type

}

void Map::createDefendUnit()

{}

void Map::createBuildingUnit()

{}

//Node.h

class Node

{

public:

Item *m_data;

Node *m_next;

Node();

virtual ~Node();

};

//Item.h

class Item

{

public:

Item();

~Item();

int m_x;

int m_y;

int m_id;

};

//AttackItem.h

class AttackItem : public Item

{

public:

int m_targetCoord;

int m_range;

int m_speed;

int m_prob;

AttackItem();

~AttackItem();

AttackItem(const AttackItem& other);

virtual void attack() = 0;

};

//Airplane.h

class Airplane : public AttackItem

{

public:

int m_airplaneId;

Airplane(int speed);

~Airplane();

virtual void attack();

};

Structure: Base->Derived1->Derived2 = Item->AttackItem->Airplane

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים