CPP מחלקה עם טמפלייט

helloworld5

New member
CPP מחלקה עם טמפלייט

שלום רב
מדוע עם אני עושה מחלקה של TEMPLATE ב CPP
template<class T, class K>class class_name
מדוע אי אפשר לעשות בסוג מחלקה כזאת את הצהרת הפונקציות בקובץ HEADER ואת המימוש בקובץ CPP ?
למה כאשר יש מחלקת TEMPLATE חייבים לממש את הפונקציות בקובץ HEADER עצמו?
 
כי הקימפול לא יכול להיות נפרד

כאשר מצהירים על פונקציה ב-a.h ומממשים אותה ב-a.cpp, אפשר להשתמש בה בקובץ b.cpp (שמכליל את a.h), והקומפיילר יקמפל כל אחד מקבצי ה-cpp בנפרד, ואח"כ המקשר יחבר את שני הפלטים של הקומפיילר.
&nbsp
כאשר הפונקציה הזאת היא template, אם זה יהיה במבנה הזה, כאשר הקומפיילר יקמפל את a.cpp, הוא לא יידע באלו instantiations משתמשים ב-b.cpp, וכאשר הוא יקמפל את b.cpp, הוא לא יוכל ליצור את ה-instantiation האלו, כי אין לו את הקוד שלהן. לכן, הוא לא יוכל ליצור אותן בשום שלב, והקימפול (או הקישור) ייכשל.
 

פרסאוס

New member
קימפול הוא הידור, קישור הוא link

במקרה של תבניות תהיה בעיה בהידור. לא תגיע לקישור.
 

helloworld5

New member
בטוחים???

ראיתי תשובה ב STACKOVERFLOW
וגם ניסיתי
עשיתי HEDER שבו הגדרתי מחלקת TEMPLATE
template<typename K, typename T>class xxx{
public:
void insert(K k, T d);}

ובCPP עשיתי

template <typename K, typename T>void xxx<K, T>::insert(K k, T d)
{
}
וזה עבד
 
תודה על הדיוק

הכוונה היתה, שגם אם הקומפיילר "יחליק" את הטעות הזו, המקשר לא יוכל למצוא את ה-instantiation, כי הוא לא נוצר מעולם.
 

helloworld5

New member
דווקא הצלחתי.

ה HEADER היה נראה כך
template<typename K>class classA{
public:
void print(K k);};
ה מימוש בקובץ CPP נפרד היה כך

template <typename K>
void classA<K>::print(K k)
{
cout << k;}
והקריאה מה MAIN הייתה כך
void main(void){
classA<int> ff;
ff.print(3);
}

פשוט אם מה MAIN עשיתי אינקלוד ל HEADER בלבד זה לא עבד
אבל אם עשיתי אינקלוד גם ל HEADER וגם למימוש ב CPP זה לא עבד
אבל...אם עשיתי אינקלוד רק ל CPP זה כן עבד
אשמח להסבר מדוע זה כך?
ואם כך, פשוט אאנקלוד רק את ה CPP של המימוש מה MAIN ואז אוכל להפריד בין HEADER למימוש
 
הסיומת לא משנה דבר

אפשר לכתוב תוכנת cpp בקובץ עם סיומת jpg, והיא תתקמפל ותרוץ.
&nbsp
אבל אם אתה שואל "כתבתי את הפונקצייה main בקובץ jpg. למה זה לא מתקמפל?" (אגב, יש שרשור נפלא ב-stackoverflow), ההנחה בקריאה סבירה היא שאתה מדבר על קובץ תמונה.
&nbsp
בדיוק באותו אופן, המושג "קובץ cpp" מציין קובץ שמעבירים לקומפיילר, ולא מכלילים אותו בקבצים אחרים.
 

helloworld5

New member
כמובן שהיא לא משנה....

אז אדייק
חילקתי את המחלקה לקובץ הצהרה(header) ולקובץ מימוש cpp
כאשר קישרתי מה main לקובץ המימוש זה עבד. למרות החלוקה לקבצים שאמרתם שהיא לא טובה
כאשר קישרתי לקובץ ההצהרה או גם לקובץ ההצהרה וגם לקובץ המימוש,זה לא עבד
לכן
1,מדוע שמעתי רבות שאומרים שלא ניתו לחלק מחלקה תבניתית לקובץ הצהרה וקובץ מימוש?
&nbsp
2,אשמח להבין למה כאשר קישרתי מהmain גם להצהרה וגם למימוש ,קיבלתי בעיה
&nbsp
תודה
 

פרסאוס

New member
אני לא בטוח שאתה משתמש נכון במונח "קישרתי"

אני חושד שאתה מתכוון ל"הכללתי".
אני צודק?
 

פרסאוס

New member
ואתה חושב ש"עבדת" על המערכת?

הכללה היא הכללה והמערכת עובדת אותו דבר.
העניין בהפרדת קבצים הוא קמפול פעם אחת. לא השגת (ולא תשיג בC++) את זה.
 

Grosseto

New member
לדעתי, זו דרך להתמודד עם הבאגים בקומפיילר

הקומפילציה של טמפלייטים ב C++ כל כך מורכבת, שיש שם באגים בשפע, אם אתה שם את ההצהרה ב CPP , הקומפיילר צריך לנחש את כל הטיפוסים, הוא אמור לעשות את זה, אבל עלול ליפול...
&nbsp
לכן ההצהרה ב H קובץ נותנת לך סיכוי יותר טוב.
אני לא ממש בטוח בקשר לזה, רק מנסיון שהיה לי פעם
&nbsp
 
למעלה