ABA


"צריך עזרה ב Member Function Pointer ב C++"
גירסת הדפסה        
קבוצות דיון פיתוח, תיכנות ובניית אתרים נושא #10169 מנהל    סגן המנהל    מפקח   Winner    צל"ש   מומחה  
אשכול מספר 10169
עידן_הכלי

   12:46   07.12.10   
אל הפורום  
  צריך עזרה ב Member Function Pointer ב C++  
 
   אהלן חבר'ה,


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

לכן הפונקציה הזאת מקבלת כפרמטר איזשהו מצביע לפונקציה שתקרא.

הבעיה היא שהמצביע שאני רוצה להעביר הוא מצביע לפונקציה של המחלקה, ולכן הקומפיילר צועק עלי ולא נותן לי לבצע את הפעולה.
הוא נותן לי להעביר רק פונקציות מחלקה שהן סטטיות! אבל הפונקציה שלי לא יכולה להיות סטטית!

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

מישהו נתקל בזה? יודע איך לפתור?

תודה,
עידן.


                                שתף        
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד

  האשכול     מחבר     תאריך כתיבה     מספר  
  אי אפשר לשלוח פוינטר למתודה רגילה. Zippo  07.12.10 16:22 1
  שמע אם תתכנן נכון זה לא יעבוד ככה.. אבל ג'וני הקטן 07.12.10 18:14 2
  בעייה מאד נפוצה בC++ Net_Boy  08.12.10 00:45 3
  עדכון עידן_הכלי 08.12.10 13:05 4

       
Zippo 
חבר מתאריך 26.5.02
7921 הודעות
   16:22   07.12.10   
אל הפורום  
  1. אי אפשר לשלוח פוינטר למתודה רגילה.  
בתגובה להודעה מספר 0
 
מכיוון שפוינטר כזה מחזיק רק כתובת של קטע קוד. ואין לו מושג על איזה אובייקט לעבוד.

בכלל, ב-Design נכון של תכנות מונחה עצמים, נדיר מאד שתיאלץ לשלוח פוינטר לפונקציה.
אז העצה הכי טובה שלי: תחשוב שוב על הדיזיין. יש מצב שאפשר לייעל אותו.

אם תתעקש על שליחה של פוינטר לפונקציה, אז כמו שאמרת, ניתן לעשות זאת בעזרת מתודה סטטית. אם אתה צריך לעבוד על אובייקט ספציפי, תקבל אותו למתודה כארגומנט.
פיתרון נוסף, הוא פונקציה גלובלית שמוגדרת FRIEND, ויש לה גישה לשדות פרטיים, וחתימה של הפונקציה תיאלץ להכיל פוינטר\רפרנס לסוג האובייקט שעליו אתה צריך לעבוד.
שיהיה בהצלחה.


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
ג'וני הקטן
חבר מתאריך 24.6.10
1166 הודעות
   18:14   07.12.10   
אל הפורום  
  2. שמע אם תתכנן נכון זה לא יעבוד ככה.. אבל  
בתגובה להודעה מספר 0
 
   אבל אם אתה מתעקש אז אתה יכול להשתמש בפונקציה המדהימה :bind אם אני לא טוענ היא נכנסה כבר לסטנדרט של C++..
זה שזה עושה בבערך זה מקבל INSTANCE של המחלקה, פונקציה והפרמטרים שהפונקציה אמורה לקבל... ומחזיר אם אני לא טועה אינסטנס של מחלקה שאם תפעיל את האופרטור () שלה זה יפעיל את הפונקציה שרצית במחלקה ששלחת לBIND..

אני לא מספיק משופשף בזה אבל אם אני לא טועה ככה זה עובד...


שוב תכנון נכון, צריך תירוץ מאד טוב בשביל לעשות את זה.. (מקרה ספציפי שמשתמשים בזה בBOOST זה שיוצרים THREAD אז זה יכול להיות כל פונקציה...)

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


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Net_Boy  לחץ כאן להצגת דירוג המשתמש
חבר מתאריך 1.4.02
17151 הודעות, 1 פידבק
   00:45   08.12.10   
אל הפורום  
  3. בעייה מאד נפוצה בC++  
בתגובה להודעה מספר 0
 
   יש WORKAROUNDS ב BOOST
אבל הדרך הנכונה ביותר לפי דעתי לעשות דבר כזה
זה להגדיר INTERFACE של CALLBACK לדוגמא
IObjectWithCallback עם מתודה פשוטה וגנרית של OnCallbackRecieved
לגרום למחלקה שלך לרשת מה INTERFACE הזה
ואז להעביר לפונקציה הסנכרונית פשוט אובייקט של IOjbectWithCallback*

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



                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
עידן_הכלי

   13:05   08.12.10   
אל הפורום  
  4. עדכון  
בתגובה להודעה מספר 0
 
   ראשית תודה על התגובות.

לבסוף פתרתי את הבעיה בצורה דיי עקומה, יצרתי מצביע סטטי שמצביע לINSTANCE של המחלקה שלי ולכן הגדרתי אותה כמחלקה שלא תומכת ב Multi-Threading.

הבעיה הגדולה שלי היא שאת הפונקציה שמקבלת את ה CALLBACK לא אני כתבתי אותה ולכן אני לא שולט בפרמטרים שהיא מעבירה.
(הפונקציה הזאת היא got_packet של WINPCAP.)

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

תודה רבה!
עידן.


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד

תגובה מהירה  למכתב מספר: 
 
___________________________________________________________________

___________________________________________________________________
למנהלים:  נעל | תייק בארכיון | מחק | העבר לפורום אחר | מחק תגובות | עגן אשכול
       



© כל הזכויות שמורות ל-רוטר.נט בע"מ rotter.net