קוד: |
#include<iostream>
using namespace std; class car { public: int seats; car operator + (car model) { return model; } }; int main() { car suz; suz.seats = 5; cout << suz.seats << endl; car nis; nis.seats = 10; cout << nis.seats << endl; suz = nis + suz; cout << suz.seats << endl; } |
קוד: |
car operator + (car model) { car plusmodel; plusmodel.seats = model.seats + this.seats; return plusmodel; } |
Anonymous : | ||
משהו כזה:
תסלח לי אם יש טעויות פעם אחרונה שכתבתי c++ היתה לפני הרבה שנים |
צפריר : |
הערה:
מהי המשמעות של פעולת החיבור? נכון שלא חייבת בעיקרון להיות משמעות לפעולה, אבל שתי הפעולות שהוגדרו כאן נראות לי מוזרות (הראשונה פשוט מחזירה את אחד המחוברים. הפעולה שבתגובה מנסה לייצר מכונית כלאיים). כמוכן שם האופרנד הוא model. האם מדובר כאן על אובייקט שהוא מכונית או דגם מכונית? |
קוד: |
class foo{ private: int val; public: int operator+(const foo & rhs) { val += rhs.val; { }; |
Anonymous : |
מה שאני לא מצליח זה לגשת לאופרנד השמאלי (או באמצעות העברה כפרמטר, או באמצעות גישה מתוך המתודה), אז איל לעז*** עושים את זה? |
קוד: |
int i=1;
int j = 2 int k; k = i + j; |
קוד: |
friend Car operator+(const Car& a, const Car& b)
{ Car c; c.seats = a.seats + b.seats; return c; } ; //in class |
עמית : | ||||
לפני הפיתרון הטכני, חשוב להבין מה המטרה ב"העמסת אופרטורים" (לא תרגום מוצלח בעיני, אבל בינתיים נישאר איתו).
פעולת החיבור היא פעולה בינארית – היא פועלת על שני "אובייקטים" ומחזירה אובייקט שלישי שהוא תוצאת הפעולה. הרעיון שעומד מאחורי "העמסת אופרטורים" הוא לשמר את ה"היגיון" שמאחורי פעולה ספציפית ולהרחיב אותו לסוג חדש של אובייקט. למשל, אם מדברים על פעולת החיבור, לכולנו ברור מה משמעות הפעולה כאשר מדובר, נניח, במספרים:
אם אני כותב כעת קוד שמגדיר מחלקה של, נאמר, וקטור דו-מימדי, אני יכול להגדיר לו אופרטורים אריתמטיים כדי לתת לו "התנהגות" מתמטית הגיונית. למשל, אני יכול להחליט שהתוצאה ההגיונית של פעולת חיבור על וקטור כזה היא חיבור של כל רכיב לרכיב המתאים. למשל, אם אני מחבר את הוקטורים (2,3) ו-(5,3) אני רוצה שהתוצאה תהיה (7,6). כלומר, צריך שיהיה הגיון מאחורי העמסת אופרטורים. נכון שבמקרה של C++ השפה לא מגבילה ואני יכול לכתוב אופרטור חיבור שיעשה דברים שלא קשורים בכלל לחיבור, אבל אז מאבדים את המשמעות של הפעולה, שצריכה להיות גם "טבעית" ומובנת למי שישתמש בקוד ויצפה ל"סוג של פעולת חיבור". לכן, לסיכום החלק הזה, אתה צריך לחשוב מה המשמעות של חיבור של שני אובייקטים מסוג Car כדי לשמור גם על הסמנטיקה של פעולת החיבור. לגבי החלק הטכני: נניח, לצורך העניין, שהכוונה שלך בחיבור של שתי מכוניות היא לייצר מכונית שלישית שמספר המושבים בה הוא הסכום של מספרי המושבים במכוניות שאתה מחבר. אופרטור בינארי, כמו למשל חיבור, הוא לא מתודה של המחלקה, כי הוא פועל על שני אובייקטים ומחזיר אובייקט חדש. הדרך הקנונית להגידר אותו הוא בתוך המחלקה, כ-friend. לפונקציה שמוגדרת בתוך מחלקה כ-friend יש גישה לכל המשתנים בכל אובייקט של המחלקה. במקרה שלך, אפשר לחשוב על ההגדרה הבאה:
הפונקציה צריכה להיות מוגדרת בתוך המחלקה Car. רק כהערה, השאלה שלך מאד בסיסית ונראה שאתה בתחילת הדרך של לימוד C++. אם תשאל אותי, כדאי שתמצא ספר טוב ותלמד בצורה מסודרת גם עקרונות כלליים של objec oriented programming וגם את עקרונות השפה. |
קוד: |
#include<iostream>
using namespace std; class car { public: int seats; friend car operator + (const car & modelA, const car& modelB) { car modelC; modelC.seats = modelA.seats + modelB.seats; return modelC; } }; int main() { car suz;//suzuki suz.seats = 5; car nis;//nissan nis.seats = 4; car newcar; newcar = suz + nis; cout <<"seats: "<< newcar.seats << endl ; } |
קוד: |
car operator + (const car & modelA, const car& modelB) {
car modelC; modelC.seats = modelA.seats + modelB.seats; return modelC; } |
קוד: |
error: ‘car car::operator+(const car&, const car&)’ must take either zero or one argument.
error: no match for ‘operator+’ in ‘suz + nis’ |
קוד: |
car operator + (car const & modelA) {
//cout << modelA.seats; car modelB ; modelB.seats = seats +modelA.seats; return modelB; } |
קוד: |
foo + bar |
קוד: |
foo.operater+(bar) |
קוד: |
class X { f(int i) {/*...*/} } |
קוד: |
X x; x.f(42); |
קוד: |
x.f(this, 42); |
קוד: |
int seats; car operator + (car model) { car modelB; modelB.seats = seats + model.seats; return modelB; } |
קוד: |
friend car operator + (car modelA, car modelB) {
modelA.seets += modelB.seets; modelA.pass += modelB.pass; return modelA; } |
קוד: |
car operator + (car modelA,car modelB) {
car modelC; modelC.seets =modelA.seets + modelB.seets; return modelC; } |
קוד: |
int w =1 + 2 |
ציטוט: | ||
השאלות שנותרו לי הם 1. האם א' מוגדר כמתודה? 2. האם friend מוגדר כמתודה? 3. האם יש אפשרות ליישם פונקציה גלובלית עם פרמטר פורמלי אחד? 4. האם ניתן לבצע העמסת אופרטורים על פעילות שאינה על אבייקטים לדוגמה ש-
|
Anonymous : | ||||
המילה מתודה היא מילה שניתן לתאר איתה כמה דברים, לא חושב שיש הגדרה סגורה לזה. יש פונקציה שחברה במחלקה ויש את כל השאר לכן לגבי 2 זה פונקציה שהיא חברה *של* המחלקה (יש לה גישה לשדות פרטיים של המחלקה), היא לא חברה *ב*מחלקה לגבי 3 אפשר לעשות מה שרוצים, השאלה מה תקבל, פונקציה גלובלית עם פרמטר אחד היא תהיה רק עם פרמטר אחד, זה עוזר לך במשהו? 4. לא ניתן. עושים את זה על ידי wrapper כשהכוונה מחלקה עוטפת. בכלל כדאי למעט בהעמסת אופרטורים ששונים מהמשמעות של האופרטור בעולם האמיתי. לדוגמה, אם יש לך מחלקה שמייצגת וקטור יהיה נכון להעמיס לה אופרטור + אבל אם יש לך מחלקה שמייצגת בעל חיים, לא לעניין לממש לה אופרטור + גם אם יש לך צורך בו, תעשה פונקציה שתבצע את הפעולה שאתה מעוניין בה |
Anonymous : |
זה פשוט כמו כל מתודה (פונקציה שחברה באובייקט לפי ההגדרה לעיל) שמופעלת עם האופרטור על האובייקט. אתה יכול לעשות מה שאתה רוצה בלי העמסת אופרטורים ויש שפות שבכלל לא מאפשרות את זה כמו java.
עדיף ללמוד java לפני C++ לפי דעתי האישית. |
Anonymous : | ||||
יש לדעתך שיטה מועדפת ליישום מבין אלו שהוזכרו? |