עבור לתוכן

עזרה לגבי העמסת operator[] בC++

Featured Replies

פורסם

שלום

יש לי מחלקה בשם ARRAY

אני צריך שני סוגים של operator[], אחד להדפסת איברים ואחד להשמה.

כלומר בmain אני רוצה שיהיה כך


main(){
ARRAY test;

test[0]=55; //קריאה לפונקציה אחת
cout << test[0]; // קריאה לפונקציה שניה

}

תודה רבה

פורסם

אתה צריך ליצור מחלקת ביניים, שהאופרטור [] יחזיר אובייקט מהסוג שלה. לאותה מחלקת ביניים, צריך שני דברים:

1. אופרטור =, שמקבל מספר שלם (או מה שאתה רוצה).

2. אופרטור המרה למספר שלם (או למה שאתה רוצה). למקרה שאתה לא מכיר, הסינטקס של זה הוא משהו כמו:

operator int ()

וסורי על העברית-מדיי, אבל אני לא סובל שהסדר מתבלבל לי... :P

עריכה: עשיתי תיקון בסינטקס.

פורסם
  • מחבר

אבל בדרך הזאת אני לא אוכל לעשות שינויים במחלקת ARRAY,שזה בדיוק המטרה שלי

אם אני אשתמש במחלקת עזר אני לא אוכל ממנה לגשת לשדות של מחלקת ARRAY (אם הבנתי נכון)

פורסם

אחד יהיה const

והשני לא

ככה אם אני לא טועה:


const int& operator[](int i) const;
int& operator [](int i);

פורסם
  • מחבר

ניסיתי עם הconst וזה לא עובד לי

הנה מה שעשיתי


array.h:

#include <iostream>
using std::cout;

class Array
{
public:
const int& operator[](int i) const
{
cout << "b";
return A[i];
};

int& operator[](int i)
{
cout << "a";
return A[i];
};


private:
int A[100];
};



main.cpp:
#include"array.h"

void main(){

Array test;
test[0] = 55;
cout << test[0];
}

בשני המקרים רצה לי הפונקציה בלי ה const מודפס a פעמיים

מה לא בסדר פה?

פורסם

קודם כל main אמור להיראות ככה:

int main(int argc, char* argv[])

{

........

return 0;

}

סתם לידע כללי, תתרגל לכתוב MAIN רק ככה.

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

פורסם

שתי הגרסאות השונות של האופרטור [] הם לשם מתן פונקציונליות עבור משתנים וקבועים.

המטרה בחתימה הראשונה (נטולת ה-const) היא לאפשר השמה (וגם קריאה) במערכים שאינם קבועים - const,

ואילו החתימה השנייה (עם ה-const) נועדה לאפשר פונקציונליות של החזרת הערך ה-i במערך גם אם המערך הוא קבוע.

ללא גרסה זו של האופרטור, אם היית מצהיר על מערך const, ומנסה להדפיס אחד מערכיו, הגרסה הראשונה לא הייתה פועלת,

כי "אינה מתחייבת" שלא לשנות את האוביקט עליו פועלת, ולכן יסרב הקומפיילר להפעילה על אוביקט קבוע, למרות שהלכה למעשה תוכן הפונק' לא משנה את האוביקט, כי אם מאפשר שינוי ע"י החזרת רפרנס אליו (מה שמאפשר שינוי מבחוץ).

באופן כללי, הקומפיילר מחליט להפעיל את הפונקציה המתאימה ע"י ה-constness של האוביקט: אם המערך קבוע, תיקרא גרסת ה-const,

ואם לאו, תיקרא הגרסה נטולת ה-const.

בתוכניתך, test הוא משתנה (לא קבוע) ולכן בשני המקרים תיקרא הפונק' המתאימה לאוביקט משתנה, ולא קבוע. (לכן ההדפסה הכפולה של a)

פורסם
  • מחבר

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

אני אנסה לפרט יותר את הבעיה ותגידו לי אם זה בכלל אפשרי

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

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

האם זה אפשרי ?

פורסם

אם הבנתי אותך נכון, וברצונך לאפשר את מה שהזכרת על משתנה מטיפוס ARRAY, אז אני לא מכיר דרך אלגנטית לעשות זאת.

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

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

cout << (*const_cast<const Array*>(test_p))[0];

כאשר test_p הוא מצביע ל-test

אבל יכול להיות שיש דרך אלגנטית יותר לעשות זאת, עליה אולי מנוסים ממני ב- c++ יוכלו לספר לך.

פורסם

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

אני אנסה לפרט יותר את הבעיה ותגידו לי אם זה בכלל אפשרי

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

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

האם זה אפשרי ?

יש אפשרות ללא שימוש באופרטורים (אולי אפשר להיתשמש בופרטורים במקרה הזה אבל אני לא יודע איך).

תיצור שתי מתודות אחת נגיד set שתקבל אינדקס ופרמטר, והשנייה נגיד get שתקבל אינדקס ותחזיר את ה VALUE באינדקס הזה.

ארכיון

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

דיונים חדשים