OCCT Handle 学习导论

基本设计思想

这是一个侵入式智能指针(类似于boost::intrusive_ptr),引用计数器直接嵌入在被管理的对象中(Standard_Transient基类),而不是单独分配内存存储计数器。

核心成员变量

private:
    Standard_Transient* entity;  // 指向被管理对象的指针

引用计数管理机制

BeginScope() - 增加引用计数

void BeginScope()
{
    if (entity != 0)
        entity->IncrementRefCounter();  // 调用对象的引用计数增加方法
}

EndScope() - 减少引用计数并可能销毁对象

void EndScope()
{
    if (entity != 0 && entity->DecrementRefCounter() == 0)
        entity->Delete();  // 引用计数为0时销毁对象
    entity = 0;
}

构造函数和析构函数

// 空构造函数
handle() : entity(0) {}

// 从指针构造
handle(const T* thePtr) : entity(const_cast<T*>(thePtr))
{
    BeginScope();  // 增加引用计数
}

// 拷贝构造函数
handle(const handle& theHandle) : entity(theHandle.entity)
{
    BeginScope();  // 增加引用计数
}

// 析构函数
~handle() { EndScope(); }  // 减少引用计数,可能销毁对象

赋值操作

void Assign(Standard_Transient* thePtr)
{
    if (thePtr == entity)
        return;  // 自赋值检查
    
    EndScope();     // 释放当前对象
    entity = thePtr;
    BeginScope();   // 管理新对象
}

类型转换系统

DownCast - 向下转型(基类到派生类)

template <class T2>
static handle DownCast(const handle<T2>& theObject)
{
    return handle(dynamic_cast<T*>(const_cast<T2*>(theObject.get())));
}

向上转型(派生类到基类)

根据编译器支持情况,提供两种方式:

  1. 类型转换操作符(默认方式):
template <class T2>
operator const handle<T2>&() const
{
    return reinterpret_cast<const handle<T2>&>(*this);
}
  1. 泛化构造函数(OCCT_HANDLE_NOCAST宏定义时):
template <class T2>
handle(const handle<T2>& theHandle) : entity(theHandle.entity)
{
    BeginScope();
}

访问操作符

T* get() const { return static_cast<T*>(this->entity); }
T* operator->() const { return static_cast<T*>(this->entity); }
T& operator*() const { return *get(); }

比较操作符

template <class T2>
bool operator==(const handle<T2>& theHandle) const
{
    return get() == theHandle.get();  // 比较指针地址
}

使用示例

// 创建对象
Handle(Geom_Point) pt1 = new Geom_CartesianPoint(1, 2, 3);
Handle(Geom_Point) pt2 = pt1;  // 引用计数变为2

// 向下转型
Handle(Geom_CartesianPoint) cartPt = Handle(Geom_CartesianPoint)::DownCast(pt1);

// 自动销毁:当pt1和pt2都超出作用域时,对象被自动删除

关键特性

  1. 线程安全的引用计数:依赖Standard_Transient的原子操作
  2. 类型安全:通过SFINAE技术确保类型转换的安全性
  3. 零开销抽象:相比原始指针几乎没有性能损失
  4. 自动内存管理:无需手动delete
  5. 循环引用检测:需要程序员注意避免

这个设计巧妙地平衡了性能、安全性和易用性,是现代C++智能指针的优秀实现。

你可能感兴趣的:(学习OCCT,OCCT,Qt)