---
layout: doc
title: calls / shadow
---
# shadow

### 名称

    shadow() - 投影某个对象中的一个或多个函数

### 语法

    object shadow( object ob, int flag );

### 描述

    如果参数 `flag` 是 1 或者不指定，当前对象会投影对象 `ob`。如果参数 `flag` 是 0 ，要么返回 0 要么返回已经投影对象 `ob` 的对象。

    主控对象中定义了 apply 方法 "valid_shadow()"，每次执行 shadow() 外部函数时主控对象都会调用此方法，如果 valid_shadow() 返回 0 那么目标对象无法被投影，这时 shadow() 函数会返回 0 而不是被投影的对象 `ob`。

    如果对象 `a` 投影对象 `b`，所有针对对象 `b` 的函数调用都会重定向到 `a`，只有 `a` 中没有定义被呼叫的函数时才会从 `b` 中呼叫（就像 a 没有投影 b 一样）。对象 `b` 中的内部方法仅限 `b` 自己调用，如果要通过 call_other() 呼叫 `b` 中的方法的话，仅对象 `a` 可以这样用。

    有二种方法可以移除投影，或者摧毁投影对象，或者摧毁被投影对象。而如果编译驱动时定义了 PACKAGE_CONTRIB，还可以使用 remove_shadow() 外部函数取消投影。

    利用投影，可以把一个对象隐藏在另一个对象后面，又可以像没有被隐藏一样运行。shadow() 外部函数可以在不改变相关对象代码的情况下改变对象的行为。举例来说，通过 shadow() 可以很容易的给不同玩家增加职业上的特殊能力，比如盗贼、战士、法师等。相比把所有特殊功能的代码都写在玩家对象中来说这种用法可以让代码更为简洁。

    请注意：如果当前对象已经投影了对象，或被对象投影，或者在任何环境中，将无法再投影任何对象，否则会报错。但是，如果对象 `ob` 已经被对象 A 投影了，还可以继续被对象 B 投影，结果是 B 投影 A，A 投影 `ob`，这也是让对象投影已投影其它对象的对象的唯一方式。另外，对象不能投影自己，即函数中参数 `ob` 不可以是 this_object()，否则会报错。

### 参考

    destruct(3), query_shadowing(3), remove_shadow(3), valid_shadow(4)

### 翻译

    雪风(i@mud.ren)
