בעיה בלינקר של VS C++ 6.0 - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

בעיה בלינקר של VS C++ 6.0


Ghosthunter

Recommended Posts

שלום,

כאשר אני מכיל את קובץ ה- H של מחלקה מסויימת הלינקר זורק לי הודעת: "error LNK2001: unresolved external symbol". אם אני מכיל את קובץ הCPP(שמכיל קישור לקובץ הH בראשו) הוא לא זורק לי שגיאה.

היכן יכולה להיות הבעיה? האם אני צריך לשנות משהו במאפייני הקובץ(ב- dependencies).

קישור לתוכן
שתף באתרים אחרים

כמה אופציות:

כמובן שאם הצהרת בקובץ H על פונקציה או משתנה EXTERN שלא נכללים בקובץ CPP שאותו אתה מנסה לקמפל, אז צריך ללנקג' אותם בייחד (כלומר תוסיף את ה-CPP שמכיל את ההגדרה של הפונקציה/משתנה לפרוייקט).

האם הקובץ H שייך לספריה מסויימת (כלומר פרוייקט שמייצר LIB?). אם כן צריך לכלול DEPENDANCY לאותו פרוייקט כדי שהלינקר ילנקג' אותם.

אופציה נוספת מעניינת: האם הגדרת abstract class עם pure virtual destructor כלומר:

class Abstract {
public:
Abstract() {}
~Abstract() = 0;
}

במקרה זה עדיין צריך מימוש ל-DTOR כיוון שיורשי המחלקה צריכים לקרוא ל-DTOR של האבא.

קישור לתוכן
שתף באתרים אחרים

יש לי מחלקה של מחרוזת ומחלקה של וקטור(template) שאני כתבתי. אם אני רושם בקובץ ה- H של המחרוזת INCLUDE לH של הוקטור, הפונ של הוקטור לא מזוהות. רק אם אני עושה INCLUDE לקובץ CPP זה עובד.

בשני קבצי הCPP יש INCLUDE לH שלהם בהתאמה.

קישור לתוכן
שתף באתרים אחרים

חייבים לעשות מימוש ל-destructor! אסור לעשות אותו pure virtual!

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

מותר גם מותר, ואף מומלץ.

פשוט צריך לזכור לצרף מימוש ל-DTOR.

לגבי unsigned: כשאתה כותב template כל הקוד שהוא template-י חייב להמצא בקובץ שאתה עושה לו #include ומכיל את ה-template, וזאת על מנת שהקומפיילר יוכל ליצור קוד מתאים לשימוש שלך ב-template. על כן לרוב תמצא קוד טמפלטי שיש לו רק קבצי H ובכלל ללא קבצי CC/CPP.

לדוגמא: רוב ה-STL בא כקבצי H. החלק שהוא CPP מתעסק בעיקר במימוש streams ולפעמים במני אלוקטורים מיוחדים.

קישור לתוכן
שתף באתרים אחרים

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

יש כאלה ששמים את המימוש בקובץ עם סיומת i או משהו כזה, אבל הם עושים לו #include גם כן אז זה לא ממש משנה (למעשה לדעתי זה גרוע יותר).

קישור לתוכן
שתף באתרים אחרים

אז לרשום:


#ifndef blabla
#define blabla

class blaaaaa {...};

blaaaaaa::blaaaaa(){...}
....



#endif

או לרשום את המימוש בתור INLINE?

(איזה כתיבה מכוערת...)

אם אתה לא רוצה שהמתודה תהיה inline אז אתה חייב לשים את המימוש בנפרד.

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

אם המתודה היא משהו דבילי של שורה אחת אז אני מניח שגם לא נורא לשים את המימוש ישר ב-CLASS.

קישור לתוכן
שתף באתרים אחרים

מותר גם מותר, ואף מומלץ.

פשוט צריך לזכור לצרף מימוש ל-DTOR.

אמרתי שאסור לעשות אותו pure, לא שאסור לעשות את ה-DTOR וירטואלי.

pure אומר שאין לו מימוש.

אפילו יותר מזה - אם יש לך פונקציות וירטואליות בקלאס, אתה חייב לעשות את ה-DTOR וירטואלי (לא רק מומלץ).

ולגבי השאלה הספציפית: באמת מומלץ להכניס את כל המימוש לקובץ עם סיומת נפרדת (נניח i או inl) ולעשות לו include בסוף הקובץ h (לפני ה-endif, כמובן).

דרך אגב, יש קומפיילרים (כמו gcc ו-KCC) שיודעים להתמודד עם זה, אבל זה לא בתקן.

קישור לתוכן
שתף באתרים אחרים

pure virtual לא אומר שאין מימוש - אלא שמוצהר שאין לה מימוש במחלקה ועל היורשים הקונקרטיים לממש בעצמם.

המקרה של destructor שהוא pure virtual הוא המקרה הקלאסי של הצורך במימוש למתודה pure virtual.

וזה לא אני אומר, זה Scott Meyers ו-Marshall Cline אומרים.

זה לא רעיון טוב לשנות את ה-design שלך בגלל בעיה מימושית מקומית שיש לה פתרון אחר. לדוגמא, עדיף לא להוסיף מתודה ל-abstract base class רק בגלל שחסרה לך מתודה pure virtual, בהנחה שיש לך פתרון אחר. ובמקרה זה - יש לך!

כמו שניתן לראות בדוגמא של Cline, מומלץ להפוך את ה-DTOR ל-pure virtual ואז לספק מימוש inline-י ריק בתוך ה-H. כך חוסכים קובץ CPP מיותר וחוסכים קריאה מיותרת לפונקציה.

קישור לתוכן
שתף באתרים אחרים

טוב, יש לי שאלה נוספת:

איך אני מוסיף לCLASS שהוגדר כTEMPLATE פונקצייה רק לסוג נתונים מסויים?

יש לי CLASS VECTOR, ואני מעוניין להגדיר לו פונ איחור רק עבור משתנה מסוג STRING שהגדרתי.

אני אני עושה את זה?

קישור לתוכן
שתף באתרים אחרים

ארכיון

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

×
  • צור חדש...