多物理场仿真 Chrono(1.5) Chrono 共享指针

本文是原网站文档翻译,介绍了Chrono中的共享指针。Chrono用符合C++11的std::shared_ptr管理“重量级对象”,简化内存管理、避免悬空指针错误。还提到使用std::make_shared的情况及Chrono的替代函数。此外,说明了从Chrono API 3.0之前版本移植到新版本的准则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为方便查阅,此文是原网站文档翻译,如有侵权,请与本人联系。

共享指针

在Chrono中,大多数“重量级对象”,如刚体、链接等,都是通过共享指针进行管理的。一个结果是,用户不必担心在创建对象后删除对象。实际上,这些共享指针在某种意义上提供了一个基本的垃圾收集机制。在这种情况下,Chrono使用STL库中符合C++11的共享指针std::shared_ptr。
shared_ptr类型的对象能够共享指针的所有权。一旦他们获得指针的共享所有权,当最后一个所有者释放该所有权时,该所有者组将负责删除指针。在这种情况下,记住shared_ptr对象在其自身被销毁后立即释放其共同拥有的对象的所有权是很有用的。
在指针上共享所有权的所有shared_ptr对象释放此所有权后,托管对象将自动删除。
使用shared_ptr对象的主要效果是用户永远不需要使用delete。这简化了内存管理,避免了与悬空指针相关的错误。
示例:创建一个对象并通过共享指针处理它。

std::shared_ptr<ChBody> my_body(new ChBody);

但是,同一块内存被两个只能指针管理时会产生错误,因为同一个对象只能用一套内存管理体系,比如

int main(int argc, const char * argv[]) {
    auto p1 = new Test; // 划分堆空间
    std::shared_ptr<Test> sp(p1); // 创建智能指针
    std::shared_ptr<Test> sp2(p1); // 创建另一个智能指针
    
    return 0;
    }

一个更好的选择是使用std::make_shared(它需要一个内存分配,速度更快)。但是,std::make_shared将为包含固定大小可向量化特征类型的类的对象使用不正确的分配器。Chrono提供了一个替代函数,它可以自动推断使用std::make_shared回退是否安全。因此,用户代码应始终使用

auto my_body = chrono_types::make_shared<ChBody>();

注意,auto和其他C++11的情况一样,意味着不需要指定
``std::shared_ptr my_body = …
在下一个示例中,构造函数调用中需要参数:

auto my_foo = chrono_types::make_shared<Foo>(par1, par2);

其他指针也可以分配给同一共享对象。示例:

auto my_foo = chrono_types::make_shared<Foo>(par1, par2);
std::shared_ptr<Foo> my_fuu = my_foo;
 
auto my_fii = FunctionReturningSharedPointer();

向下转换共享指针依赖于dynamic_pointer_cast的使用<…>(…)通过static_pointer_cast<…>(...):完成静态强制转换

从Chrono API的3.0之前版本移植

Chrono API的3.0之前版本使用了自定义共享指针类ChSharedPtr。
这已过时且并被std::shared_ptr替换.如果遵循以下准则,修改旧代码以使用Chrono API的v.3.0和更高版本将非常简单:

  • Types:
    • 旧版本
      ChSharedPtr<Foo>
      
    • 新版本
      std::shared_ptr<Foo>
      
  • 创建共享指针:
    • 旧版本
      ChSharedPtr<Foo> my_var(new Foo(arg1, arg2));
      
    • 新版本
      auto my_var = chrono_types::make_shared<Foo>(arg1, arg2);
      
  • 如果Foo的构造函数不接受任何参数,那么:
    • 旧版本
      ChSharedPtr<Foo>  my_var(new Foo);
      
    • 新版本
      auto my_var = chrono_types::make_shared<Foo>();
      
  • 如果变量已经在其他地方声明为共享指针:
    • 旧版本
      ChSharedPtr<Foo>  my_var;
      my_var = ChSharedPtr<Foo>(new Foo(arg1, arg2));
      
    • 新版本
      std::shared_ptr<Foo> my_var;
      my_var = chrono_types::make_shared<Foo>(arg1, arg2);
      
  • 复制构造函数:
    • 旧版本
      ChSharedPtr<Foo>  var1;
      ChSharedPtr<Foo> var2(var1);
      ChSharedPtr<Foo> var3 = ChSharedPtr<Foo>(var1);
      
    • 新版本
      std::shared_ptr<Foo> var1;
      std::shared_ptr<Foo> var2(var1);
      auto var3 = std::shared_ptr<Foo>(var1);
      
  • 来自原始指针的构造函数:
    • 旧版本
      Foo* my_pointer;
      ChSharedPtr<Foo> my_var(my_pointer);
      
    • 新版本
      Foo* my_pointer;
      std::shared_ptr<Foo> my_var(my_pointer);
      
  • 指针转化:
    • 旧版本
      ChSharedPtr<Base>  var1;
      ChSharedPtr<Derived> var2 = var1.DynamicCastTo<Derived>();
      ChSharedPtr<Derived> var3 = var1.StaticCastTo<Derived>();
      
    • 新版本
      std::shared_ptr<Base> var1;
      auto var2 = std::dynamic_pointer_cast<Derived>(var1);
      auto var3 = std::static_pointer_cast <Derived>(var1);
      
  • 对包装指针的访问:
    • 旧版本
      ChSharedPtr<Foo> my_var;
      Foo* my_pointer = my_var.get_ptr();
      
    • 新版本
      std::shared_ptr<Foo> my_var;
      Foo* my_pointer = my_var.get();
      
  • 测试NULL(空)共享指针,例如在断言或条件:
    • 旧版本
      ChSharedPtr<Foo> my_var;
      assert(!my_var.IsNull());
      
    • 新版本
      std::shared_ptr<Foo> my_var;
      assert(!my_var);
      
  • 应使用dynamic_pointer_cast显式完成类型测试:
    • 旧版本

      ChSharedPtr<Bar> my_var;
      if (my_var.IsType<Foo>()) {
          ....
      }
      
    • 新版本

      std::shared_ptr<Bar> my_var;
      if (std::dynamic_pointer_cast<Foo>(my_var)) {
          ...
      }
      

返回首页目录,交流学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值