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_;
};
  • 32
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值