עבור לתוכן

C++, פונקציית CallBack למחלקה [עזרה]

Featured Replies

פורסם

שלומות,

אני משתדל ללמוד מעט מהאיטרנט בזמני החופשי, ואודה לכם אם תוכלו להסביר לי נושא שנתקעתי בו.

אני כותב מחלקה של תור (Queue) שאמור להכיל סוגי משתנים שונים (Template וכו'). כחלק מכתיבת המחלקה, יש צורך בסידור (Sort) וכדי שזה יהיה אפשרי לכל סוג (Type) אני צריך שהמשתמש יוכל לספק פונקצייה שמשווה בין שני ערכים.

במלים אחרות, אני רוצה שאם המשתמש יוצר תור של Struct כלשהו, הוא יספק פונקציית השוואה בין שני Struct* והמחלקה תעבוד כמו שצריך.

במקרה שהמשתמש לא יספק פונקציית השוואה, המחלקה תשתמש באופרטורים הרגילים (>, < ו =).

איך עושים את זה? יש דרך לשמור פונקצייה כמשתנה בתוך אובייקט של מחלקה (או משהו כזה)?

מקווה שנסחתי מובן ומדויק מספיק כדי שיהיה ברור.

תודה מראש

*פונקציה במבנה של:

int fn(Type one, Type two)

פורסם

ב++c ניתן להגדיר מצביעים לפונקציות. חפש בגוגל c++ pointer to function.

פורסם
  • מחבר

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

אני מכריז על ה-Pointer בחלק הPrivate של המחלקה:

int (*fn)(ElemType, ElemType);

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



template <typename ElemType>
PQueue<ElemType>::PQueue()
{
heap = new ElemType [initSize];
nUsed = 0;
nAllocated = initSize;


fn = &PQueue<ElemType>::OperatorCmp;
}

את הפוקנציה OperatorCmp אני מוסיף בחלק ה-Private והיא נראית ככה:



template <typename ElemType>
int PQueue<ElemType>::OperatorCmp(ElemType one, ElemType two)
{
if (one == two) return 0;
return (one < two ? –1 : 1);
}


ובכל זאת אני מקבל הודעות שגיאה מסוג:



error C2440: '=' : cannot convert from 'int (__thiscall PQueue<ElemType>::* )(ElemType,ElemType)' to 'int (__cdecl *)(ElemType,ElemType)'
1> with
1> [
1> ElemType=int
1> ]
1> There is no context in which this conversion is possible
1> c:\users\bill carson\documents\visual studio 2005\projects\ass 7. pathfinder\ass 7. pathfinder\pqueueheap.cpp(30) : while compiling class template member function 'PQueue<ElemType>::PQueue(void)'
1> with
1> [
1> ElemType=int
1> ]

רעיונות?

תודה!

פורסם

אני לא סגור על זה, אבל נראה לי שזה לא אפשרי שמצביע לפונקציה יצביע על מתודה של מחלקה. עדיף שתגדיר את פונקציית ההשוואה מחוץ למחלקה.

חוץ מזה, שים לב שאם ל-ElemType לא מוגדרים האופרטורים == ו-> אז המתודה OperatorCmp בכלל לא תתקמפל לך, גם אם אתה בכלל לא משתמש בה.

יש עוד אופציה שהיא להשתמש ב-template ו-template specialization. הרעיון הוא להגדיר את OperatorCmp בתור פונקציה טמפלייטית (מחוץ למחלקה שלך) עם מימוש דיפולטי, ותוכל לדרוס אותה עבור טיפוסים ספציפיים באמצעות template specialization, ככה:

template <typename ElemType>
int OperatorCmp(ElemType& one, ElemType& two) {
// default implementation
}

ואז עבור טיפוסים שאין להם == ו-> אתה עושה כזה דבר:

template <>
int OperatorCmp<MyType>(MyType& one, MyType& two) {
// specialized implementation
}

עריכה: קבל תיקון, מסתבר שאפשר גם ש-OperatorCmp יהיה חלק מהמחלקה שלך, וה-specialization יהיה ככה:

template <>
int PQueue<MyType>::OperatorCmp(MyType& one, MyType& two) {
// specialized implementation
}

פורסם

תוכל להשתמש במתודה כפי שאתה רוצה אם היא תהיה סטטית.

ארכיון

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

דיונים חדשים