shadow() ======== FUNKTION -------- :: object shadow(object ob, int flag) ARGUMENTE --------- :: object ob - das vom shadow betroffene Objekt int flag - 0 fuer eine Shadow-Existenzabfrage 1 fuer Shadow durch previous_object() BESCHREIBUNG ------------ :: Wenn nicht 0 ist, wird das aktuelle Objekt dem Objekt obj als Shadow uebergeworfen. Bei Erfolg wird das geshadowte Objekt zurueckgegeben, sonst 0. Wenn 0 ist, wird entweder 0 oder das geshadowte Objekt zurueck gegeben. Wenn ein Objekt A ein Objekt B beschattet, werden alle call_other() fuer B auf A umgeleitet. Wenn die an B gerufene Funktion in A existiert, so wird sie in A gerufen, bei Nichtexistenz in B. A ist das einzige Objekt, welche die beschatteten Funktionen mit call_other() in B aufrufen kann, selbst B kann nicht per call_other() diese Funktion rufen. Alle intern verwendeten Funktionen arbeiten jedoch weiterhin normal. Das aufrufende Objekt muss vom Master-Objekt die Erlaubnis haben, als Shadow zu wirken. Es gibt folgende Kriterien fuer eine erfolgreiche Beschattung: - das zu beschattende Objekt ob: - ist weder ein access_rights-Objekt noch ein ROOT-Objekt - gibt beim Aufruf von query_prevent_shadow(beschatter) eine 0 zurueck - beschattet selbst niemanden - hat kein '#pragma no_shadow' gesetzt - der Beschatter: - wird nicht selbst (direkt) beschattet - beschattet noch niemanden (sonst folgt direkter Abbruch) - hat kein environment() - definiert/beschattet keine Methode, die im beschatteten Objekt ob als nomask definiert ist Beschattet man ein Objekt A mit einem Objekt B und dann das Objekt A zusaetzlich mit einem Objekt C, so wird eine Beschattungshierarchie erstellt: B macht shadow(A, 1) B->A C macht shadow(A, 1) C->B->A BEISPIELE --------- :: // wenn: B beschattet A, dann shadow(find_object(A), 0) == B // 3 Objekte beschatten in Hierarchie (liegt auch im Pfad) --- aa.c --- void fun() { printf("%O [a] fun()\n", this_object()); } void fun3() { printf("%O [a] fun3()\n", this_object()); } --- bb.c --- int fun() { printf("%O [b] fun()\n", this_object()); find_object("/doc/beispiele/shadow/aa")->fun(); } void fun2() { printf("%O [b] fun2()\n", this_object()); find_object("/doc/beispiele/shadow/aa")->fun3(); this_object()->fun3(); } void do_shadow(object target) { shadow(target, 1); } --- cc.c --- int fun() { printf("%O [c] fun()\n", this_object()); find_object("/doc/beispiele/shadow/aa")->fun(); } void fun3() { printf("%O [c] fun3()\n", this_object()); } void do_shadow(object target) { shadow(target, 1); } // darauf arbeitender Code object a, b, c; destruct("/doc/beispiele/shadow/aa"); a = load_object("/doc/beispiele/shadow/aa"); destruct("/doc/beispiele/shadow/bb"); b = load_object("/doc/beispiele/shadow/bb"); destruct("/doc/beispiele/shadow/cc"); c = load_object("/doc/beispiele/shadow/cc"); b->do_shadow(a); c->do_shadow(a); printf("--- a->fun() ---\n"); a->fun(); printf("--- b->fun() ---\n"); b->fun(); printf("--- c->fun() ---\n"); c->fun(); printf("--- b->fun2() ---\n"); b->fun2(); // ... und seine Ausgabe: --- a->fun() --- /doc/beispiele/shadow/cc [c] fun() /doc/beispiele/shadow/bb [b] fun() /doc/beispiele/shadow/aa [a] fun() --- b->fun() --- /doc/beispiele/shadow/cc [c] fun() /doc/beispiele/shadow/bb [b] fun() /doc/beispiele/shadow/aa [a] fun() --- c->fun() --- /doc/beispiele/shadow/cc [c] fun() /doc/beispiele/shadow/bb [b] fun() /doc/beispiele/shadow/aa [a] fun() --- b->fun2() --- /doc/beispiele/shadow/bb [b] fun2() /doc/beispiele/shadow/aa [a] fun3() /doc/beispiele/shadow/cc [c] fun3() // Der erste Aufruf von b::fun2() in a findet sofort a::fun3()! Der // Driver nimmt an, dass alle Shadows ab c bei Rufen von b nach a // schon ihre Chance hatten. // Der zweite Aufruf allerdings ist auf b und wird beim Durchgeben // an a von c uebernommen. SIEHE AUCH ---------- :: Generell: shadow(E) Rechte: query_allow_shadow(M), query_prevent_shadow(L) Informationen: query_shadowing(E) 8.Aug 2007 Gloinson