深拷贝完整版

   function deepClone(target) {
        // 创建一个 WeakMap 来保存已经拷贝过的对象,以防止循环引用
        const map = new Map();

        // 辅助函数:判断一个值是否为对象或函数
        function isObject(target) {
          return (
            (typeof target === "object" && target) || // 检查是否是非null的对象
            typeof target === "function" // 或者是函数
          );
        }

        // 主要的拷贝函数
        function clone(data) {
          // 基本类型直接返回
          if (!isObject(data)) {
            return data;
          }

          // 对于日期和正则对象,直接使用它们的构造函数创建新的实例
          if ([Date, RegExp].includes(data.constructor)) {
            return new data.constructor(data);
          }

          // 对于函数,创建一个新函数并返回
          if (typeof data === "function") {
            return new Function("return " + data.toString())();
          }

          // 检查该对象是否已被拷贝过
          const exist = map.get(data);
          if (exist) {
            return exist; // 如果已经拷贝过,直接返回之前的拷贝结果
          }

          // 如果数据是 Map 类型
          if (data instanceof Map) {
            const result = new Map();
            map.set(data, result); // 记录当前对象到 map
            data.forEach((val, key) => {
              // 对 Map 的每一个值进行深拷贝
              result.set(key, clone(val));
            });
            return result; // 返回新的 Map
          }

          // 如果数据是 Set 类型
          if (data instanceof Set) {
            const result = new Set();
            map.set(data, result); // 记录当前对象到 map
            data.forEach((val) => {
              // 对 Set 的每一个值进行深拷贝
              result.add(clone(val));
            });
            return result; // 返回新的 Set
          }

          // 获取对象的所有属性,包括 Symbol 类型和不可枚举的属性
          const keys = Reflect.ownKeys(data);
          // 获取对象所有属性的描述符
          const allDesc = Object.getOwnPropertyDescriptors(data);
          // 创建新的对象并继承原对象的原型链
          const result = Object.create(Object.getPrototypeOf(data), allDesc);

          map.set(data, result); // 记录当前对象到 map

          // 对象属性的深拷贝
          keys.forEach((key) => {
            result[key] = clone(data[key]);
          });

          return result; // 返回新的对象
        }

        return clone(target); // 开始深拷贝
      }

在OSG(OpenSceneGraph)中,`osg::Group`类代表了一个节点组,它包含了多个子节点。由于`osg::Group`内部可能包含复杂的节点图,完整的深拷贝通常涉及到递归地复制所有成员节点。下面是一个简化版的示例代码,展示了如何创建一个`osg::Group`的深拷贝: ```cpp #include <osg/Group> #include <osg/Object> class GroupDeepCopy : public osg::Referenced { public: explicit GroupDeepCopy(const osg::Group* original) : original_(original) {} // 创建一个深拷贝的Group virtual ~GroupDeepCopy() override { if (original_) { osg::ref_ptr<osg::Group> copy = new osg::Group; for (const osg::Node* node : original_->children()) { osg::ref_ptr<osg::Node> copiedNode = dynamic_cast<osg::Node*>(node->clone(osg::CopyOp::DEEP_COPY)); if (copiedNode) copy->addChild(copiedNode); } // 将深拷贝替换原始的指针 original_ = copy.get(); } } private: const osg::Group* original_; }; // 使用示例 osg::Group sourceGroup; // 原始的Group实例 osg::Group* deepCopiedGroup = new GroupDeepCopy(&sourceGroup); ``` 这个例子中,我们创建了一个名为`GroupDeepCopy`的新类,它接受一个指向原始`osg::Group`的指针作为构造参数。在析构函数中,通过迭代并深度复制每个子节点,生成了一个新的`osg::Group`实例。 请注意,实际使用中可能需要处理更复杂的场景,例如处理非节点类型的孩子、引用计数以及内存泄漏等问题。此外,如果你直接操作`osg::Object`的`clone`方法,可能会遇到循环引用的问题,这时需要手动断开一些引用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值