| |
| 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 <flag> nicht 0 ist, wird das aktuelle Objekt dem Objekt obj |
| als Shadow uebergeworfen. Bei Erfolg wird das geshadowte Objekt |
| zurueckgegeben, sonst 0. |
| Wenn <flag> 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 |