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

שאלה ב- C++


Armageddon26

Recommended Posts

1) מה הדרך הכי יעילה (מבחינת זמן ריצה) להפוך char ל-std::string?

2) האם יש אובייקט "כללי" ב-c++? משהו כמו Object ב-Java?

אם כן אז יש לו פונקציה שדומה ל-toString כדי שאוכל להפוך אותו ל-string?

תודה ושנה אזרחית טובה!

:xyxthumbs:

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

1. יש פורום לשפות תכנות עילית. הועבר.

2. באמצעות הבנאי של string.

3. אתה יכול להגדיר משתנה מטיפוס *void. זה אומר שהמשתנה הוא מצביע, אבל לא אומר לאיזה טיפוס. אחר כך אפשר באמצעות casting להמיר אותו חזרה למה שאתה רוצה.

4. אין ב-++C פונקציה סטנדרטית להפוך אובייקט למחרוזת. אם אתה רוצה להיות מסוגל להדפיס את האובייקט, אתה יכול להגדיר את האופרטור >> של cout להיות מסוגל להדפיס אותו, כמו בדוגמה כאן:

http://www.codeproject.com/KB/cpp/cfraction.aspx?fid=15432&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=10

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

אז אם האובייקט הכללי הזה הוא הוא בטוח char או string אז אפשר יהיה לעשות לו פשוט cout?

ואתה בטוח שיש ל-string קונסטרקטור מ-char?

הייתי בודק בעצמי אבל כרגע אין לי IDE של C++ על המחשב.. עוד מעט זה יסיים להוריד...

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

ל-string יש constructor מ-char* אל תדאג. מצד שני הוא מבצע הקצת דינמית, ולכן תלוי במקרה שלך אבל זה לא בהכרח הדרך היעילה ביותר.

אכן ניתן להדפיס עם cout כל char* ו-string. אם אתה רוצה להדפיס Unicode (כלומר wstring או wchar_t*) אז צריך להשתמש ב-wcout.

לגבי נושא הירושה, יש צורך בהבהרה:

ב-C++ בפירוש אין מחלקה שכולם יורשים ממנה, וזו פשוט לא חלק מהפילוסופיה של השפה. הגישה של C++ אומרת שאתה לא משלם על מה שאתה לא צריך, או במילים אחרות: אם רוצים, צריך שאפשר יהיה לייצר עם מחלקות קוד יעיל כמו קוד ללא מחלקות. אם כל האובייקטים היו יורשים מ-"object" ולכולם היתה מתודה וירטואלית של ToString, אז כולם היו משלמים את המחיר, מעבר למה שצריך קוד C רגיל.

בנוסף, קיום מחלקה שכולם יורשים ממנה נקרא לפעמים cosmic hierarchy וזה נחשב לרוב תכנון גרוע ב-C++ עקב הבעיות שהוא מייצר.

אם אתה רוצה, אתה יכול להגדיר בקוד שלך מחלקה ולרשת את שאר המחלקות ממנה.

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

הקוד הבא גרם להדפסה של התו 'a' ולאחריו כל מיני שטויות.


char c = 'a';
string s(&c);
cout << s << endl;

אז זה לא מתאים לי בשביל להמיר כמו שצריך מתו למחרוזת...

אשמח להצעה אחרת

עריכה:


void* c;
c = new char('a');
cout << *c << endl;

לא מתקמפל. ואם אני מנסה להדפיס את c אז זה פשוט מדפיס כתובת.

אין דרך לפתור את זה? אפשר להניח ש-c מצביע ל-string או ל-char.

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

הקוד הבא גרם להדפסה של התו 'a' ולאחריו כל מיני שטויות.

כדי שהבנאי של string מתוך char* יעבוד, המחרוזת חייבת להיות null-terminated (כלומר להסתיים ב-0\). במקרה שלך זה לא מתקיים כי אחרי הזכרון שהוקצה לתו a יש זבל אקראי. כדי שזה יעבוד תצטרך להגדיר משהו כמו:


char s[2]={'a','\0'};
string(s);


char c = 'a';
string s(&c);
cout << s << endl;

אז זה לא מתאים לי בשביל להמיר כמו שצריך מתו למחרוזת...

אשמח להצעה אחרת


void* c;
c = new char('a');
cout << *c << endl;

לא מתקמפל. ואם אני מנסה להדפיס את c אז זה פשוט מדפיס כתובת.

אין דרך לפתור את זה? אפשר להניח ש-c מצביע ל-string או ל-char.

אתה לא יכול לעשות dereference ל-*void. הביטוי c* חסר משמעות. על מנת שיהיה בעל משמעות, אתה צריך לעשות casting מפורש:



cout << *(char*)c << endl;

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

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

ניתן לבנות string מתוך char* שהוא NULL-terminated שזה ה-string הסטנדרטי ב-C. ובגלל שהוא הסטנדרטי, לא צריך לעבוד קשה כדי ליצור אותו, הקומפיילר יעשה זאת בשבילך.


char s1[] = "a";
char s2[2] = {'a', '\0'}; /* effectively the same as s1 */
const char *s3 = "a"; /* not the same as s2 but more commond then s2 */
string(s1);
string(s2);
string(s3);

המרה מ-void*:

וכאן אנו רואים בדיוק למה זה מסוכן, ועדיף להמנע מזה אלא כאשר ממש צריך.

באופן כללי, עדיף להמיר ל-const char* אם אין צורך בשינוי המחרוזת, כי אתה לא יודע מאיפה הגיע המצביע, ומה בדיוק עושה הפונקציה שקוראים לה.


void *p = "hello world"; /* allowed in C, not in C++ */
const void *p2 = (const void *)"hello world"; /* allowed in C++ */
...
...
char *s = (char*)p;
s[0] = 'j'; /* OH NOES! We are writing on constant data memory area! This is an error! */
...
char *s2= (char*)p2; /* yes, this is allowed even in C++ */
s2[0] = 'j';/* ERROR! */

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

עוד הערה קטנה אחרונה: כשמבצעים casting ב-++C, נהוג להשתמש באופרטור המתאימים של ++C, ולא בהמרה ה"רגילה" של C. כלומר, להשתמש באחד מהאופרטורים const_cast, static_cast, dynamic_cast ו-reinterpret_cast.

במקרה הספציפי הזה, למיטב זכרוני, צריך להשתמש ב-static_cast.

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

הכתיבה לאיזור "ליטרלי", לא רק שהיא שגיאה לוגית בתכנית אלא שבמערכות מסויימות זה יגרום לתכנית לעוף מיידית.

הנה דוגמה על לינוקס:



#include <stdio.h>

int main()
{
char* s = "Pello World";

s[0] = 'H';
puts(s);

return 0;
}

לאחר קומפילצה והרצה נקבל:


$ gcc write_const.c -o wrc
$ ./wrc
Segmentation fault

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

ארכיון

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

×
  • צור חדש...