כותב |
|
אורח אורח
הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין הודעות: 12647
|
נשלח בתאריך: 19 August 2007 בשעה 19:35 | | IP רשוּם
|
|
|
|
אוקיי, אז הצטוויתי לכתוב מחלקה בשם "god" שתאפשר ליצור רק אובייקט אחד שלה ושאחריו כל נסיון יצירת אובייקט יחזיר אותו אובייקט...
מימשתי את זה ככה שכדי להשתמש במחלקה צריך ליצור מצביע, אני יודע שאפשר וצריך לעטוף עוד מחלקה מסביב למצביע, ושהאינקפסולציה בקוד פגומה לכל היותר, אבל רציתי לדעת אם עשיתי את המחלקה עצמה בצורה אופטימלית...
הסיבה לשימוש במצביע היא שמשתנה רגיל יכול להצביע רק למקום אחד, ואי אפשר לשנות את ההצבעה שלו בצורה גלובאלית...
הנה הקוד:
god.h
קוד:
#pragma once
class god { public:
int index;
god() { static int count = 0; static god* onlyGod; if (!(index = count++)) { onlyGod = this; } else { this->~god(); const_cast<god*>(this) = onlyGod; } }
~god() { index = -1; } }; |
|
|
Main.cpp:
קוד:
#include <iostream> #include "god.h"
using namespace std;
int main() { god *g1, *g2, *g3; g1 = new god(); g2 = new god(); g3 = new god(); cout << (*g1).index << g1 << endl; cout << (*g2).index << g2 << endl; cout << (*g3).index << g3 << endl; delete g1; return 0; } |
|
|
|
חזרה לתחילת העמוד |
|
|
Free Thinker משתמש מתחיל
הצטרף / הצטרפה: 04 August 2007
משתמש: מנותק/ת הודעות: 10
|
נשלח בתאריך: 20 August 2007 בשעה 13:25 | | IP רשוּם
|
|
|
|
אם הבנתי נכון, מה שאתה רוצה נקרא בשפה המקצועית Singleton.
הנה, תקרא כאן את הקוד. לפי דעתי זה הפתרון האופטימלי:
http://forum.codenet.ru/showpost.php?p=206376&postcount=8
__________________ Free Thinkers ARE dangerous! (C) S.o.a.D.
chown -R us /home/your/.base
|
חזרה לתחילת העמוד |
|
|
אורח אורח
הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין הודעות: 12647
|
נשלח בתאריך: 20 August 2007 בשעה 13:50 | | IP רשוּם
|
|
|
|
תודה.
נכון, חיפשתי singleton c++ בגוגל ולא הצלחתי למצוא משהו נורמאלי...
זה בעקרון לכל שימוש פרקטי מעולה, אבל התרגיל שהביאו לי זה שכל האובייקטים יהפכו לזהים, יכול להיות שאני טועה וסתם צריך לעשות skeleton שמתנהג טיפה מוזר...
תודה בכל מקרה
|
חזרה לתחילת העמוד |
|
|
אלצ'קו אחראי פורומים
ג2ר פ33תי
הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת הודעות: 609
|
נשלח בתאריך: 24 August 2007 בשעה 16:45 | | IP רשוּם
|
|
|
|
לא הצלחת? הנה משהו שדומה לפיתרון:
קוד:
template<typename T> T* getSingleton() { static T* singletonObject = 0; if (singletonObject == 0) { singletonObject = new T(); } return singletonObject; } |
|
|
|
חזרה לתחילת העמוד |
|
|
אורח אורח
הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין הודעות: 12647
|
נשלח בתאריך: 24 August 2007 בשעה 17:12 | | IP רשוּם
|
|
|
|
זהו, את זה הצלחתי, אבל לא הצלחתי לעשות התנהגות אוטומטית כזאת, כאילו מחלקה שתתנהג כרגיל עם קונסטרוקטור ופשוט כל המופעים שלה יהפכו אוטומטית לאותו דבר...
אני מניח שזה בלתי אפשרי ושבטח לא ביקשו את הבלתי אפשרי (:
תודה על המימוש ששלחת!
|
חזרה לתחילת העמוד |
|
|
אלצ'קו אחראי פורומים
ג2ר פ33תי
הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת הודעות: 609
|
נשלח בתאריך: 24 August 2007 בשעה 18:53 | | IP רשוּם
|
|
|
|
אני מניח שזה אפשרי עבור אובייקטים דינאמיים (שנוצרים בעזרת new) אם תעמיס את אופרטור new עבור המחלקה שלך, אבל זה לא ישפיע על אובייקטים סטטיים (לוקאליים או גלובאליים שלא נוצרים בעזרת new).
אפשרות אחרת היא יצירת מחלקת מעטפת לסינגלטונים, הפיכת הבנאי של המחלקה שלך לפרטי, והגדרת מחלקת המעטפת כחברה.
|
חזרה לתחילת העמוד |
|
|
אורח אורח
הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין הודעות: 12647
|
נשלח בתאריך: 24 August 2007 בשעה 19:55 | | IP רשוּם
|
|
|
|
זהו, על זה כבר חשבתי וגם ציינתי את זה למעלה
|
חזרה לתחילת העמוד |
|
|
תנסה את זה אורח
הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין הודעות: 12647
|
נשלח בתאריך: 24 August 2007 בשעה 23:04 | | IP רשוּם
|
|
|
|
הרעיון ב-Singleton הוא להחביא את הקונסטרקטור של המחלקה,במקומה לכתוב פונקציה שמפעילה את הקונסטרקטור פעם אחת ליצירת האובייקט הראשוני והחזרת פויינטר או רפרנס (תלוי בשפה) בכל הפעמים הבאות.
לפי מה שאני הבנתי אתה רוצה ליצור העתקים של האובייקט הראשון שיצרת. אם זה הכוונה אז פתרון אפשרי הוא:
להחזיק פויינטר/רפרנס לאובייקט הראשון שנוצר מן המחלקה ומשתנה אינדקציה על פיו להתנות בקונסטרקטור העתקה של האובייקט הראשוני לכל אובייקט אחר שנוצר. הבעיה היא שאני לא בטוח שזה יעבוד עם כל קומפיילר. הקוד הבא נוסה ב-Visual Studio 2005 ועבד:
קוד:
class Cool{
private :
static Cool* E; // pointer to the first object created from this class
// must be initiated by NULL value.
public :
int x,y;
// constructor
Cool(){
if (E) // if an object has allready been created from this class
// then copy its values of x and y.
{
x = E->x;
y = E->y;
}
else E = this; // else E gets the address of the
// first objected created from this class.
}
};
|
|
|
קובץ ה-CPP:
קוד:
Cool* Cool::E = NULL;
void main()
{
Cool c;
c.x = 5;
c.y = 6;
Cool b,y,x;
Cool* z = new Cool();
}
|
|
|
|
חזרה לתחילת העמוד |
|
|
shoshan מנהל האתר
הצטרף / הצטרפה: 16 July 2005 מדינה: Israel
משתמש: מנותק/ת הודעות: 4637
|
נשלח בתאריך: 24 August 2007 בשעה 23:29 | | IP רשוּם
|
|
|
|
כמובן שאפשר להשתמש בהעתקה מהאובייקט הראשוני, אבל אז כל אובייקט לעצמו עם הזיכרון שלו, שינוי אובייקט יביא לחוסר התאמה בינו לבין האובייקט הראשון (:
__________________ עד מתי רשעים יעלוזו?
עַל כֵּן אֶמְאַס וְנִחַמְתִּי עַל עָפָר וָאֵפֶר.
|
חזרה לתחילת העמוד |
|
|
ממממ אורח
הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין הודעות: 12647
|
נשלח בתאריך: 24 August 2007 בשעה 23:59 | | IP רשוּם
|
|
|
|
תשמע אני חושב שאתה לא סגור על עצמך מבחינת השאלה...
אם אתה רוצה ליצור מופעים חיים תלותיים, ובכל פעם שהאובייקט הראשון שיצרת (או כל אובייקט אחר), יעבור שינוי כלשהו זה יגרור פעולה מסויימת על שאר האובייקטים מאותה משפחה אז יש DP-ים התנהגותיים אחרים שניתן להסתמך עליהם כמו Mediator ו-Observer.
|
חזרה לתחילת העמוד |
|
|