מחלקות ב-C

lexter

New member
מחלקות ב-C

היי, ברצוני לדעת אם יש דבר כזה מחלקות ב-C? כמו ב-C++? אני חושב שלא,בגלל ש-C היא לא OOP.. אבל אני לא בטוח.. אשמח לקבל תשובה..
 

selalerer

New member
יש כל מיני מנגנונים מסובכים שאנשים

מימשו בפרוייקטים אלו ואחרים בשביל לתכנת OOP או איזה בן-כלאים של OOP ופרוצדורלי במשך השנים. אפשר לומר שאחד מהמנגנונים האלה היה קומפיילר של Objective C שאח"כ התפתח ל++C. אם אתה רוצה לתכנת OOP, תשתמש ב-++C. תוכל עדיין להשתמש בכל המנגנונים של C כשאתה רוצה.
 

dove2

New member
כמעט הכל

אם הוא ירצה להשתמש ב setjmpq/longjmp הוא לא יוכל להשתמש ב exceptions מצד שני, אני ממש לא מאמין שהוא ירצה
 

dove2

New member
השאלה למה אתה קורא "מחלקה"

struct נותן לך פונקציונאליות של אנקפסולציה (בעברית "כמיסות" או משהו מוזר כזה). זה כבר 30% מגישת OO אפקט של הורשה ניתן להשיג על ידי הכלה - כלומר שאחד החברים ב struct הוא struct בעצמו (בדר"כ החבר הראשון). זה כבר עוד 30% מגישת OO פולימורפיזם תצטרך לממש לבד על ידי משחק קצת מכוער עם פוינטרים לפונקציות. זה אולי טיפה מעצבן במיוחד למי שלא מורגל אבל זה בהחלט אפשרי. מסקנה א- אם רוצים - אפשר לתכנת קוד מונחה עצמים ב C, יש הרבה פרוייקטים שכתובים ככה. מסקנה ב- אם הולכים לתכנת מונחה עצמים, אז אם אפשר עדיף בשפה שתפנק אותך לפי הצרכים שלך, כלומר C++.
 

lexter

New member
הכוונתי מחלקה

שהיא כאילו כמו ב-C++.. שאני מכניס לה פונקציות ומשתנים.. חייב להיות משהו,כי בנו את C++ עם C...
 

dove2

New member
ב struct אתה נותן משתנים בלבד

שיוך מתודה למחלקה הוא עניין של סינקס בלבד, ואין הבדל מהותי בין קריאה למתודה
list.push(123);​
לקריאה לפונקציה על מבנה מסויים
push(&list, 123);​
אגב, מבחינת הקומפיילר זה באמת כמעט אותו דבר, כי כשאתה קורא למתודה הוא שם על המחסנית גם את הכתובת של המחלקה עצמה בדיוק כאילו שלחת אותה כפרמטר לפונקציה.
 

zbobo

New member
בSTRUCT..

יש אפשרות להרשאות גישה למשתנים, כאילו לעשות ממברים כPUBLIC וכו' כמו שיש במחלקות? אני יודע שבSTRUCT יש אפשרות לעשות קונסטרקטור ודיסטראקטור..
 

selalerer

New member
ב-++C ה-struct הוא בדיוק כמו class

פשוט שברירת המחדל שלו היא public ולא private. ב-C ה-struct הוא בסך הכל מקבץ של משתנים.
 

zbobo

New member
כן אבל אפשרי

לעשות שם משתנים פריבאט? ואם כן אז איך אני ניגש אליהם מבחוץ?
 

dove2

New member
ב- C הכל public

כדי לעשות משהו private עושים הסתרה אמיתית. למשל, עובדים עם כתובת בלבד, כאשר המשתמשים בטיפוס מכירים אותו רק באמצעות forward declaration המופיעה בקובץ h בתוך קובץ ה C יש הגדרה מלאה של המבנה, וכך הפונקציות שמשתמשות במבנה כן מכירות את הפרטים.
/* H */ struct List; void push(List* list, int val); int pop(List* list); /* C */ #include ..H struct List { ... ... }; void push(List* list, int val) { ... } int pop(List* list) { ... }​
 

selalerer

New member
כמו שהיראו לך קודם.

typedef struct { //... }c1; void c1_ctor(c1 *o) { //.... } void c1_dtor(c1 *o) { //.... }​
 

dove2

New member
עושים לבד פונקציות init ו- close

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

zbobo

New member
הנה דוגמא

מקטע קוד שכתבתי פעם
struct sTrigger{ // List record type int ID; // ID of trigger float Radius; // Radius of trigger zone float PosX; // Trigger position float PosY; // float PosZ; // float ScaleX; // Trigger scalse values float ScaleY; // float ScaleZ; // int Type; // Trigger type bool Active; // TRUE if active FALSE otherwise cMesh Meshe; // Holds the trigger meshe cObject Object; // sTrigger *Prev, *Next; sTrigger() { Prev = Next = NULL; Active = FALSE; } ~sTrigger() { delete Next; Meshe.Free(); Object.Free();} };​
אם אי אפשר לעשות משתנים כפריבאט אז איך זה מתאים לכמיסות? או שאולי לא כל כך הבנתי אז מזה כמיסות..
 

dove2

New member
כמיסות

כמיסות מתייחס לעובדה שמאגדים מספר דברים יחד (מתוך בבילון: encapsulate - לעטוף בקרום, לסגור בבועה). המשתנים הללו שמאוגדים יחד יכולים להיות ציבוריים או פרטיים, מבחינת הקומפיילר אין הבדל בינם, וכאשר אתה מעביר/משתמש/יוצר/עושה-משהו עם קפסולה כזו (אובייקט) - כל המשתנים יעברו ללא קשר לציבוריותם. האבחנה בין פרטי וציבורי היא רק בדיקה בזמן הקומפילציה כדי לעזור למפתח להגן על עצמו מטעויות, בזמן ריצה אין הבדל בינהם כלל. לא נוצר קוד מכונה שונה עבור משתנים ציבוריים ופרטיים. האבחנה בין פרטי וציבורי עוזרת לאכוף מוסכמות בין מפתחים שהיו קיימות. למשל, מקובל במקומות מסויימים להוסיף קו-תחתי בתחילת שמות של משתנים פרטיים כדי להבחין אותם ממשתנים שמותר לגעת בהם. לגבי הדוגמה שהבאת, כפי שסלע אמר הבאת קוד ב C++. שים לב שכיום רוב הקומפיילרים הנפוצים אינם ספציפיים ל C או ל-C++ אלא מראש מיועדים ל C++ ומאפשרים לקמפל גם C משום ש C מהווה ב 99% מעין subset ל C++. לכן קומפיילרים הם יחסית סבלניים גם לדברים שאינם אמורים להיות ב C "קלאסי". ואם אתה חובב סביבת מיקרוסופט יש נטיה כללית בכלל להיות סבלני לדברים לא סטמדרטיים. בדר"כ כאשר אתה נותנים לקובץ סיומת C (בניגוד לסיומת C++,Cpp,cxx וכו') הקומפיילר משער שמדובר ב C קלאסי, בחלק מהקומפיילרים יש דגלי קומפילציה שאפשר להעביר כדי לבקש במיוחד שיקפיד על קוד תואם C ויוציא אזהרות אם לא.
 

selalerer

New member
ל-encapsulate יש משמעות של

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