OpenCascade源码剖析:Standard_Transient根类

2024-03-08 12:12

本文主要是介绍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_;
};

这篇关于OpenCascade源码剖析:Standard_Transient根类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/787050

相关文章

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。