עבור לתוכן

יצירת אובייקט חדש ללא אובייקט C++

Featured Replies

פורסם

אני רוצה להכניס לרשימה אובייקט בלי לעשות איזה אובייקט זמני..

למה אני מתכוון:

בJAVA זה יראה ככה


List<Card> lCard=new List<Card>();
lCard.add(new Card(1,2))

ההיתיחסות כאן היא ל NEW CARD()

המחלקה CARD היא מחלקה שאני עשיתי..

מה שעשיתי ונתקעתי הוא:


class Deck{
private:
int numOfCards;
static list<Card> deck;
static intgr;
public:
Deck(){
if (++intgr==1){
deck.push_back()
}

}

}

מה אני שם בPUSH_BACK?

פורסם

deck.push_back(Card(1,2));

לחילופין, אתה יכול להגדיר את deck בתור <*list<Card, ואז אתה יכול לדחוף באמצעות new - אבל אתה צריך לזכור שכשאתה מוחק מהרשימה, אתה חייב לעשות גם delete.

פורסם
  • מחבר

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


static{
/*CODE*/
}

ששמים אותו בתוך המחלקה (מן פונקציה בעד עצמה..)

פורסם

לא.

בקובץ המימוש, אתה צריך ליצור את האיברים. בהנחה שהקלאס שלך מוגדר בקובץ deck.h, אז בקובץ deck.cpp אתה צריך להגדיר:

int Deck::intgr = 0;

יכול להיות שאתה צריך ליצור גם את האיבר deck, אני לא סגור על זה (נסה ותראה).

(אגב, שים לב שבהצהרה על intgr, שכחת לתת לו טיפוס. חוץ מזה, כדאי לתת לו שם יותר אינפורמטיבי)

פורסם
  • מחבר

וואלה עכשיו אני יעשה אותו INT וזה אמור להיות קיצור ל integration...

בקשר לקונסטרקטורים ודיסטרקטורים, נהוג לממש אותם בH. או .CPP?

פורסם

בעקרון עדיף לממש בקובץ cpp. נראה לי שבמקרה של קונסטרקטור/דסטרקטור, אין שום יתרון על קובץ h.

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

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

class A {
int doSomething(x) { return x+1; }
};

אז כשאתה קורא לפונקציה (doSomething(x, הקומפיילר פשוט יחליף את הקריאה ב-x+1.

אגב, אין סיבה לקצר שמות של משתנים ל-5 אותיות. עדיף לשים שם מלא ושלא יבלבל, אלא אם זה ארוך מדי (10 אותיות זה לא ארוך.... 40 אותיות זה כן).

פורסם

חידוד ודגשים:

אם שמים מימוש (definition) של מתודה בתוך הגדרת המחלקה עצמה, אז המימוש הוא inline.

ניתן גם לשים את המימוש בתוך ה-h בצורה הבאה, ואז הוא לא inline:


class C
{
void foo() { cout << "foo" << endl; } // C::foo() is inline
void bar(); // C::bar is NOT inline
void fred(); // C::fred IS inline, see below!
}

// Not recommended! non inline functions are usually declared in the module (CPP, CC, etc.)
void C::bar()
{
cout << "bar" << endl;
}

inline void C::fred()
{
cout << "fred" << endl;
}

אחד המקרים שבהם נרצה לספק מימוש לפונקציה בתוך H אבל בלי שהיא תהיה inline זה כשמשתמשים ב-templates.

פורסם

מה קורה אם שני קבצי cpp שונים עושים אינקלוד לקובץ הזה? זה לא יגרום לכפילות במימוש?

פורסם

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

תחשוב על זה ככה:

אתה רוצה טמפלטים, ואף קומפיילר (חוץ מאחד) לא תומך ב-export templates. לכן אתה חייב לשים את המימוש ב-H.

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

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

אגב יש קומפיילרים שמקמפלים טמפלטים לא בשלב הקומפילציה אלא בשלב ה-link!

תתחיל לקרוא מפה ותמשיך הלאה:

http://parashift.com/c++-faq-lite/templates.html#faq-35.12

why can't we all just get along?

ארכיון

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

דיונים חדשים