OpenCascade源码剖析:Standard_Transient根类

Standard_Transient是OCCT继承体系最顶层的根类,Transient在编程中具有一定的语义,与Persistent相对应,通常用于描述数据的持久性或持久性存储。

  • Transient,意味着数据是临时的或瞬态的,它们不会被持久化保存,意味着对象只存在于内存中,一旦程序终止或对象生命周期结束时,它们就会消失。
  • Persistent,意味着数据是持久化的,它们被存储在某种持久化存储介质,如数据库或者磁盘文件,并且在程序终止后仍然存在。程序重新启动时,该对象的数据仍然可以加载到内存中。

Standard_Transient类主要提供了三个机制,内存分配,RTTI和引用计数

内存分配器

Standard_Transient类中,一开始就有一个宏DEFINE_STANDARD_ALLOC,此宏是在类的层级重载了new和delete操作符,重载了oeprator new(),placement operator new(),数组operator new[]以及相应delete版本。

重载的内存分配函数实现是调用的Standard::Allocate,内部通过内存管理工厂获得内存分配器策略

Standard_MMgrRoot* Standard_MMgrFactory::GetMMgr()
{
  static Standard_MMgrFactory aFactory;
  return aFactory.myFMMgr;
}

Standard_Address Standard::Allocate(const Standard_Size size)
{
  return Standard_MMgrFactory::GetMMgr()->Allocate(size);
}

Standard_MMgrRoot定义了分配器策略接口类,并有三个版本的实现类

三个分配器分别是优化的分配器,标准分配器和Intel TBB分配器

RTTI,反射信息

Standard_Transient提供了一些类型反射信息接口,用于运行时类型识别

  • get_type_descriptor
  • DynamicType :运行时具体类型
  • IsInstance : 是否是某种类型的实例
  • IsKind: 是否是某种类的派生类型

所有继承自Standard_Transient的类,需要通过DEFINE_STANDARD_RTTIEXT和IMPLEMENT_STANDARD_RTTIEXT宏来注册RTTI信息,就能实现 上面的反射功能,

我们可以看到,Standard_Transient通过一个称之为type_descriptor的类Standard_Type来实现RTTI功能,该类是一个描述类,用于记录类的元信息,例如类名,基类等。每个Standard_Transient派生类都有一个静态成员函数get_type_descriptor,其实现返回一个描述该类信息的static Standard_Type对象,每一个类都有一个与之对应的静态Standard_Type对象,get_type_descriptor获取这个对象后,就能通过这个对象知道类的一些元信息。

Standard_Type源码如下:

class Standard_Type : public Standard_Transient
{
public:

  Standard_CString SystemName() const { return mySystemName; }

  Standard_CString Name() const { return myName; }

  Standard_Size Size() const { return mySize; }

  const opencascade::handle<Standard_Type>& Parent () const { return myParent; }

  __declspec( dllexport ) Standard_Boolean SubType (const opencascade::handle<Standard_Type>& theOther) const;

  __declspec( dllexport ) Standard_Boolean SubType (const Standard_CString theOther) const;

  __declspec( dllexport ) void Print (Standard_OStream& theStream) const;

  template <class T>
  static const opencascade::handle<Standard_Type>& Instance()
  {
    return opencascade::type_instance<T>::get();
  }

  __declspec( dllexport ) static 
    Standard_Type* Register (const char* theSystemName, const char* theName,
                             Standard_Size theSize, const opencascade::handle<Standard_Type>& theParent);

  __declspec( dllexport ) ~Standard_Type ();

  public: typedef Standard_Transient base_type; static const char* get_type_name () { return "Standard_Type"; static_assert(opencascade::is_base_but_not_same<Standard_Transient, Standard_Type>::value, "OCCT RTTI definition is incorrect: " "Standard_Transient" " is not base class of " "Standard_Type"); static_assert(&get_type_name == &Standard_Type::get_type_name, "OCCT RTTI definition is misplaced: current class is not " "Standard_Type"); } __declspec( dllexport ) static const opencascade::handle<Standard_Type>& get_type_descriptor (); __declspec( dllexport ) virtual const opencascade::handle<Standard_Type>& DynamicType() const override;

private:

  Standard_Type (const char* theSystemName, const char* theName,
                 Standard_Size theSize, const opencascade::handle<Standard_Type>& theParent);

private:
  Standard_CString mySystemName;  
  Standard_CString myName;        
  Standard_Size mySize;           
  opencascade::handle<Standard_Type> myParent; 
};

引用计数

Standard_Transient类提供了侵入型的引用计数,包含如下三个接口,实现引用计数是为了实现类似智能指针的对象生命周期管理机制,避免使用裸指针,具体实现将在后面详述。

附宏展开后的Standard_Transient类申明如下:

class Standard_Type;

namespace opencascade {
  template <class T> class handle;
}

class Standard_Transient
{
public:
  void* operator new (size_t theSize) 
  { 
      return Standard::Allocate (theSize); 
  } 
  
  void operator delete (void* theAddress) 
  { 
      Standard::Free (theAddress); 
  } 
  
  void* operator new[] (size_t theSize) 
  { 
      return Standard::Allocate (theSize); 
  } 

  void operator delete[] (void* theAddress) 
  {
      Standard::Free (theAddress); 
  } 

  void* operator new (size_t, void* theAddress) 
  { 
      return theAddress; 
  } 

  void operator delete (void*, void*) 
  { 
  }

public:
  Standard_Transient() : myRefCount_(0) {}

  Standard_Transient (const Standard_Transient&) : myRefCount_(0) {}

  Standard_Transient& operator= (const Standard_Transient&) { return *this; }

  virtual ~Standard_Transient() {}

  __declspec( dllexport ) virtual void Delete() const;

public: 
  typedef void base_type;

  static const char* get_type_name () { return "Standard_Transient"; }

  __declspec( dllexport ) static const opencascade::handle<Standard_Type>& get_type_descriptor ();

  __declspec( dllexport ) virtual const opencascade::handle<Standard_Type>& DynamicType() const;

  __declspec( dllexport ) Standard_Boolean IsInstance(const opencascade::handle<Standard_Type>& theType) const;  

  __declspec( dllexport ) Standard_Boolean IsInstance(const Standard_CString theTypeName) const;  

  __declspec( dllexport ) Standard_Boolean IsKind(const opencascade::handle<Standard_Type>& theType) const;

  __declspec( dllexport ) Standard_Boolean IsKind(const Standard_CString theTypeName) const;

  __declspec( dllexport ) Standard_Transient* This() const;

public:
  Standard_Integer GetRefCount() const { return myRefCount_; }

  __declspec( dllexport ) void IncrementRefCounter() const;

  __declspec( dllexport ) Standard_Integer DecrementRefCounter() const;

private:
  mutable volatile Standard_Integer myRefCount_;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/439032.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言基础】:深入理解指针(三)

文章目录 深入理解指针一、冒泡排序二、二级指针三、指针数组3.1 指针数组模拟二维数组 四、字符指针变量五、数组指针变量5.1 数组指针变量是什么&#xff1f;5.2 数组指针变量的初始化 六、二维数组传参的本质 深入理解指针 指针系列回顾&#xff1a; 【C语言基础】&#xf…

Ubuntu 24.04 抢先体验换国内源 清华源 阿里源 中科大源 163源

Update 240307:Ubuntu 24.04 LTS 进入功能冻结期 预计4月25日正式发布。 Ubuntu22.04换源 Ubuntu 24.04重要升级daily版本下载换源步骤 (阿里源)清华源中科大源网易163源 Ubuntu 24.04 LTS&#xff0c;代号 「Noble Numbat」&#xff0c;即将与我们见面&#xff01; Canonica…

Java代码审计安全篇-目录穿越漏洞

前言&#xff1a; 堕落了三个月&#xff0c;现在因为被找实习而困扰&#xff0c;着实自己能力不足&#xff0c;从今天开始 每天沉淀一点点 &#xff0c;准备秋招 加油 注意&#xff1a; 本文章参考qax的网络安全java代码审计&#xff0c;记录自己的学习过程&#xff0c;还希望各…

揭示/proc/pid/pagemap的力量:在Linux中将虚拟地址映射到物理地址

pagemap的力量&#xff1a;在Linux中将虚拟地址映射到物理地址 一、/proc/pid/pagemap简介二、了解虚拟地址到物理地址的转换三、利用/proc/pid/pagemap进行地址转换3.1、访问/proc/pid/pagemap3.2、pagemap文件的数据和结构 四、页表、页框架的相关概念五、总结 一、/proc/pid…

信号处理-探索相邻数据点之间的变化和关联性的操作方法

当前值减去前一个值&#xff0c;乘上当前值与前一个值差值的绝对值 当前值减去后一个值&#xff0c;乘上当前值与后一个值差值的绝对值。 意义何在&#xff1f; 当前值减去前一个值&#xff1a;表示当前数据点与前一个数据点之间的变化量。当前值与前一个值差值的绝对值&…

【Linux】软件管理器yum和编辑器vim

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、Linux下安装软件的方案1.1 源代码安装1.2 rpm安装1.3 yum安装 二、Linux软件…

外贸常用的出口认证 | 全球外贸数据服务平台 | 箱讯科技

出口认证是一种贸易信任背书&#xff0c;对许多外贸从业者而言,产品的出口认证和当前的国际贸易环境一样复杂多变&#xff0c;不同的目标市场、不同的产品类别,所需要的认证及标准也不同。 国际认证 01 IECEE-CB IECEE-CB体系的中文含义是“关于电工产品测试证书的相互认可体…

记一次简单的获取虚拟机|伪终端shell权限

场景描述 某个系统是ova文件&#xff0c;导入虚拟机启动&#xff0c;但是启动后只有一个伪终端权限&#xff0c;即权限很小&#xff0c;如何拿到这个虚拟机的shell权限呢&#xff1f; 实际操作 这次运气比较好&#xff0c;所遇到的系统磁盘并没有被加密&#xff0c;所以直接…

吴恩达深度学习笔记:神经网络的编程基础2.1-2.3

目录 第一门课&#xff1a;神经网络和深度学习 (Neural Networks and Deep Learning)第二周&#xff1a;神经网络的编程基础 (Basics of Neural Network programming)2.1 二分类(Binary Classification)2.2 逻辑回归(Logistic Regression) 第一门课&#xff1a;神经网络和深度学…

c++ 11 新特性 不同数据类型之间转换函数之reinterpret_cast

一.不同数据类型之间转换函数reinterpret_cast介绍 reinterpret_cast是C中的一种类型转换操作符&#xff0c;用于执行低级别的位模式转换。具体来说&#xff0c;reinterpret_cast可以实现以下功能&#xff1a; 指针和整数之间的转换&#xff1a;这种转换通常用于在指针中存储额…

如何学习、上手点云算法(三):用VsCode、Visual Studio来debug基于PCL、Open3D的代码

写在前面 本文内容 以PCL 1.14.0&#xff0c;Open3D0.14.1为例&#xff0c;对基于PCL、Open3D开发的代码进行源码debug&#xff1b; 如何学习、上手点云算法系列&#xff1a; 如何学习、上手点云算法(一)&#xff1a;点云基础 如何学习、上手点云算法(二)&#xff1a;点云处理相…

【数据结构】二、线性表:6.顺序表和链表的对比不同(从数据结构三要素讨论:逻辑结构、物理结构(存储结构)、数据运算(基本操作))

文章目录 6.对比&#xff1a;顺序表&链表6.1逻辑结构6.2物理结构&#xff08;存储结构&#xff09;6.2.1顺序表6.2.2链表 6.3数据运算&#xff08;基本操作&#xff09;6.3.1初始化6.3.2销毁表6.3.3插入、删除6.3.4查找 6.对比&#xff1a;顺序表&链表 6.1逻辑结构 顺…

基于pytest的证券清算系统功能测试工具开发

需求 1.造测试数据&#xff1a;根据测试需要&#xff0c;自动化构造各业务场景的中登清算数据与清算所需起来数据 2.测试清算系统功能&#xff1a; 自动化测试方案 工具设计 工具框架图 工具流程图 实现技术 python, pytest, allure, 多进程&#xff0c;mysql, 前端 效果 测…

Web开发介绍,制作小网站流程和需要的技术【详解】

1.什么是web开发 Web&#xff1a;全球广域网&#xff0c;也称为万维网(www World Wide Web)&#xff0c;能够通过浏览器访问的网站。 所以Web开发说白了&#xff0c;就是开发网站的&#xff0c;例如网站&#xff1a;淘宝&#xff0c;京东等等 2. 网站的工作流程 1.首先我们需…

【Godot4自学手册】第二十一节掉落金币和收集

这一节我们主要学习敌人死亡后随机掉落金币&#xff0c;主人公可以进行拾取功能。 一、新建金币场景 新建场景&#xff0c;节点选择CharacterBody2D&#xff0c;命名为Coins&#xff0c;将场景保存到Scenes目录下。 1.新建节点 为根节点依次添加CollisionShape2D节点&#…

阿里云服务器使用教程_2024建站教程_10分钟网站搭建流程

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网aliyunfuwuqi.com以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流…

Dubbo基础入门二

8、Dubbo协议 服务调用 8.1 服务端 启动过程深入分析 我们查看一下服务启动的过程 ProtocolFilterWrapper.export 好我们进入DubboProtocol.export 创建服务 分析我们的Handler 我们接着返回刚才位置 下面的super方法里面会创建服务&#xff0c;ChannelHandlers.wrap会对hand…

2024年3月8日蚂蚁新村今日答案:以下哪一项传统武术项目入选了人类非物质文化遗产代表作名录?太极拳还是咏春拳

蚂蚁新村是一个虚拟社区。在这个虚拟社区中&#xff0c;用户可以参与各种活动&#xff0c;比如生产能量豆、做慈善捐赠等。同时&#xff0c;蚂蚁新村也提供了一些知识问答环节&#xff0c;用户在参与的过程中可以增进知识。这些问答内容往往涉及广泛的主题&#xff0c;如文化、…

idea Gradle 控制台中文乱码

如下图所示&#xff0c;idea 中的 Gradle 控制台中文乱码&#xff1a; 解决方法&#xff0c;如下图所示&#xff1a; 注意&#xff1a;如果你的 idea 使用 crack 等方式破解了&#xff0c;那么你可能需要在文件 crack-2023\jetbra\vmoptions\idea.vmoptions 中进行配置&#xf…

git分布式管理-头歌实验标签

一、创建标签 任务描述 现在你已经成了项目负责人&#xff0c;由你负责发布版本&#xff0c;你需要在发布一个版本之前&#xff0c;给该版本对应的代码打上标签&#xff0c;以便于管理和标识。 本关任务&#xff1a;为最近一次提交打上标签。 相关知识 在开发过程中&#xff0c…