שלום

Giladovich

New member
שלום

ניסיתי להשתמש ב"טריק הפשוט והידוע", לבעייה בה שני קבצים צריכים לעשות include אחד לשני. בפרוייקט שלי, שכולל כ-13 קבצים, כל קובץ עושה include לכמה קבצים אחרים. בכל אחד מקבצי ה-h הוספתי את ה-
#ifndef __THIS_HEADER_NAME #define __THIS_HEADER_NAME #endif​
עכשיו - למיטב הבנתי לא משנה כמה פעמים אני אעשה include לכל אחד מקבצי ה-h, הוא יוגדר פעם אחת, בדיוק בגלל ההגבלות שנתתי עם ה-ifndef. מסתבר שהבנתי היא לא משהו (
) כי אני מקבל שגיאות מסוג: redefinition, syntax error, ולבסוף גם: fatal error C1903: unable to recover from previous error(s); stopping compilation אולי חשוב לציין שאני עובד בסביבת העבודה Visual Studio 6.0. מה יכולה להיות הבעיה, ומה הפתרון, אודה מאוד לכל תשובה, גלעדוביץ'.
 

hatulflezet

New member
אין מספיק מידע

אם תפרסם לפחות את הודעות השגיאה המלאות כפי שנותן לך אותן הקומפיילר - יהיה קצת יותר קל להבין באיזה כוון הבעיה שלך. בגדול, יכול להיות שיש לך בעיה של קדימויות - אם הבנתי נכון מה שעשית. יש לך אולי INCLUDE הדדי של קבצים? כלומר - קובץ 1 עושה INCLUDE לקובץ 2 ו קובץ 2 לקובץ 1? יש לך משתנים גלובליים? שאולי צריכים EXTERN?
 

vinney

Well-known member
חצופלצת

הוא הגדיר בראש כל קובץ את אותו המקרו, כך שהמקרו נקרא על ידי הפרה-פרוססור מספר פעמים, וכל פעם הוא קיבל redefinition error, כמה שזה מפתיע.
 

Giladovich

New member
לא, הוא לא.

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

hatulflezet

New member
למה

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

vinney

Well-known member
זה לא הכינוי שלך? אופסי ../images/Emo13.gif ../images/Emo52.gif

הדיסלקציה שלי באה לידי ביטוי
 

Giladovich

New member
../images/Emo26.gif

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

hatulflezet

New member
אז זהו שלא

IFDEFעים עוזרים כשיש לך הגדרות חוזרות - וזה מונע עיבוד כפול של הקבצים. כשיש לך הכלה הדדית אתה נכנס לבעית קדימויות. אם מדובר במחלקות - אתה יכול לפתור את זה עם forward decleration.
 

Giladovich

New member
אוקיי

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

vinney

Well-known member
יש, למה אין

רק תוודא שאתה לא מגדיר את אותו הדבר בשני קבצים שונים, ואם כן, אז תדאג באמת ל externים במקומות הנכונים. ככלל לא מגדירים משתנים בקובץ header, אלא רק טיפוסים, קבועים (defineים) והצהרות לפונקציות. אם ההגדרות זהות להגדרות שכבר היו, לא תקבל שגיאה. אם אתה מקבל redifinition זה אומר שאתה מגדיר אחרת משהו שכבר הוגדר, או מגדיר מקרו/טיפוס קיים מחדש. אתה יכול לוודא הגדרה חד ערכית בעזרת קטע כזה: #ifndef __DEFINED_TYPE_SOMETHING typedef int something #define __DEFINED_SOMETHING #endif לכל טיפוס/משתנה אבל דעתי האישית היא שאם יש לך הכלות הדדיות, אז לא עשית את הפרוייקט שלך נכון, זה פשוט לא אמור לקרות אם עובדים כמו שצריך.
 

hope2drive

New member
דעתי

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

vinney

Well-known member
דווקא הדוגמא שלך זה לא דורש את זה

משום שתמיד אתה יכול להגדיר הצהרה class person; וזהו, וזה הפתרון במקרה של מחלקות. את הinclude עושים בקובץ cpp לשני המחלקות, אבל לא אחת בתוך השניה, וכך הבעיה נפתרת.
 

hatulflezet

New member
לא מדוייק

ראשית, את הבאת דוגמאת OOP - במיקרה כזה יש forward declearation על מנת להמנע מהכללה הדדית של קבצים. באופן כללי, אין שום דבר "טבעי" בהכללה הדדית - וזה באופן כללי מראה על תכנון לקוי - זה מראה על ליקוי ב-incapsulation (אין לי מושג איך לקרא לזה בעברית)
 

VoodooKid

New member
נרמול... ../images/Emo8.gif

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

vinney

Well-known member
הבנת הנקרא

אם תקרא טוב טוב את מה שכתבתי, תראה שרשמתי להחליף את "THIS_HEADER_NAME" בשם קובץ הheader בו זה נכתב, ולא לשים שורה זהה בכל הקבצים. בנוסף, אם, למשל, היית בודק ב MSDN מה אומרת השגיאה הזאת, היית יכול להבין את זה גם בלי שאגיד לך.
 

hope2drive

New member
יש לי טיפ חשוב בשבילך

מנסיוני עם הכללות כאלה. אולי אתה כבר יודע אותו, אבל ליתר בטחון. קודם כל, אפשר להכליל את קובץ1 בתוך קובץ2 ובאותו זמן את קובץ2 בתוך קובץ1 באצמעות הטריק הנ"ל. אני עשיתי את זה, וזה עובד. אפשרות אחת היא שכפי שכבר אמרו היא שלא השתמשת ב-extern בצורה נכונה. אבל זה לא הטיפ שרציתי לתת לך. הטיפ הוא כזה (והוא נוגע רק לעבודה עם פרויקטים מרובי-הכללות כאלה) : אחרי כל שינוי שאתה עושה באחד מהקבצים, אל תשתמש בפקודה Build (קיצור F7) בשביל ליצור מחדש את ה-exe. השתמש תמיד בפקודה Rebuild All אחרת הלינקינג יתבצע באופן שגוי ותקבל הודעות.
 
למעלה