עבור לתוכן

C++, איך מגדירים Global Struct?

Featured Replies

פורסם

האם יש דרך להגדיר מבנה גלובלי, שיהיה זמין למס' מחלקות שונות ללא צירוף header כל אחת מהן?

צירוף המבנה ל-header יוצר לי בעיות redefinition מכיוון שאני עושה include לכל המחלקות ב-main.

פורסם

תשתמש במקרואים:

define, ifndef

הם מאפשרים לך לך לבדוק אם כבר הגדרת מאקרו מסויים(שתגדיר אותו לפני הSTRUCT שלך). אם לא הגדרת אותו כבר, אתה צריך להגדיר אותו.

פורסם
  • מחבר

אפשר איזה דוגמא עם ה-DEFINE וה-STRUCT?

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

יש לי CLASS A לדוגמא:

class A{
my_struct sturct a;

public:
void function_A(my_struct get_a);
}

ו-CLASS B לדוגמא:

class B{
int b;

public:
void function_A(my_struct get_a, int b);
}

כמובן שאני אצטרך להגדיר בשניהם את my_struct ב-header.

הבעיה מתרחשת כאשר אני עושה ב-main שלי include לשני ה-CLASSES.

main.cpp


#include classA.h
#include classB.h

ושאלה לא קשורה, אני מגדיר friend class רק כשאני אני רוצה גישה ישירה לשדות של המחלקה השניה?

אם אני משתמש רק בפונקציות שלה אז אני לא צריך להגדיר friend class?

פורסם

אתה לא צריך להגדיר את האובייקט בקובץ ה-H.

אתה צריך להצהיר עליו. כלומר, משהו כמו:


extern struct myStruct;

אח"כ אתה צריך להגדיר אותו באחד מקבצי ה-CPP, ורק באחד מהם. ה-LINKER כבר ידע להשתמש בו.

ושאלה לא קשורה, אני מגדיר friend class רק כשאני אני רוצה גישה ישירה לשדות של המחלקה השניה?

אם אני משתמש רק בפונקציות שלה אז אני לא צריך להגדיר friend class?

אתה מגדיר FRIEND כשאתה רוצה להשתמש במשהו מהאובייקט שאין לך גישה ישירה אליו בדר"כ. בגדול, זה כל מה שהוא PRIVATE או PROTECTED.

פורסם

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

הפתרון הוא מה שהציע UnsignedInteger, שנקרא double inclusion protection.

הקטע הוא לעטוף כל קובץ header בשורות האלה:

#ifndef FILENAME_H
#define FILEMANE_H

// contents of filename.h here

#endif

(כשבמקום FILENAME_H תשים את שם הקובץ)

זה גורם לכך שאם כבר עשינו include פעם אחת לקובץ, אז הוא לא יעשה לו include שוב.

פורסם
  • מחבר

^ עבד עשר, תודה! :xyxthumbs:

פורסם

עוד משהו שכדאי לחשוב עליו:

אם קובץ A.H עושה include לקובץ B.H וגם קובץ B.H עושה include לקובץ A.H נוצר מעגל של include-ים.

לפעמים כל מה שצריך זה include guard (מה שהציעו כאן בפורום) אבל לפעמים זה מצביע על בעיה אמיתית בתכנון מבנה התוכנה.

בד"כ (לא תמיד) עדיף לתכנן מבנה כך שאין מעגילם (או מחזורים) בעץ שנוצר ע"י include. זה לא רק יוצר בעיה טכנית עם קומפילציה, זה לפעמים מצביע על באג עמוק יותר ב-design. כמעט תמיד אפשר לחשוב ולתכנן מחדש כך שאין מעגלים ב-include-ים.

לפעמים באמת אין ברירה. מחלקה A צריכה שירותים ממחלקה B (אולי היא מקבלת אותו כפרמטר?) ומחלקה B צריכה את מחלקה A (אולי היא מכילה member מסוג A).

הפתרון המקובל במקרה זה הוא הוא להשתמש במצביעים ל-B בלבד במחלקה A, ולהגדיר משהו שידוע כ-forward declaration:


class B; // this is the forward decleration

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

בצורה זו מחלקה A לא צריכה ממש את ההגדרה של B, ולא צריך לעשות #include ל-B.

פורסם
  • מחבר

הבעיה לא נבעה ממה שאתה חושב.

ה-CLASSES צריכים אחד את השני ויודעים אחד על השני.

הגדרתי עוד לפני כן, בדיוק כמו שכתבת, ע"י Forward deceleration.

הבעיה היתה עם המבנים.

אבל בכל מקרה יכול להיות שיש לי בעיה תכנונית, אחרי הכל זאת הפעם הראשונה שאני כותב תוכנית ב-OOP וגם יותר מידי ניסיון בתכנות אין לי חוץ מקורס תכנות 1 ב-C לפני כמעט 4 שנים...

וכל הנושא של CLASSES וצורת השימוש בהם די זר לי.

פורסם

אל תדאג יותר מדי. כל זה בא עם הנסיון. העיקר תמשיך לתכנת. עדיף תוכנית אמיתית עם תכנון בעייתי מתכנון טוב שלא בנו ממנו תוכנית :)

פורסם

עיין ערך MS?

פורסם

ועובדה שזו מערכת ההפעלה הנפוצה ביותר לשימוש ביתי. למרות בעיות התכנון :)

ארכיון

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

דיונים חדשים