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