蓝桥ROS机器人之现代C++学习笔记 第 5 章 智能指针与内存管理

举报
zhangrelay 发表于 2022/04/10 23:36:44 2022/04/10
【摘要】   为何一定要学习现代C++,因为在ROS中应用非常广,不学基础程序都看不懂的。 举例说明: 其实描述并不准确的,ROS1/2中使用的指针包括: std::shared_ptrstd::unique_ptrstd::weak_ptr  例如: virtual void publish(std...

 

为何一定要学习现代C++,因为在ROS中应用非常广,不学基础程序都看不懂的。

举例说明:

其实描述并不准确的,ROS1/2中使用的指针包括:

  1. std::shared_ptr
  2. std::unique_ptr
  3. std::weak_ptr 

例如:


      virtual void
      publish(std::unique_ptr<MessageT, MessageDeleter> & msg)
       {
        this->do_inter_process_publish(msg.get());
        if (store_intra_process_message_) {
          // Take the pointer from the unique_msg, release it and pass as a void * 
          // to the ipm. The ipm should then capture it again as a unique_ptr of 
          // the correct type. 
          // TODO(wjwwood): 
          // investigate how to transfer the custom deleter (if there is one) 
          // from the incoming unique_ptr through to the ipm's unique_ptr. 
          // See: http://stackoverflow.com/questions/11002641/dynamic-casting-for-unique-ptr 
           MessageT * msg_ptr = msg.get();
           msg.release();
          uint64_t message_seq =
            store_intra_process_message_(intra_process_publisher_id_, msg_ptr, typeid(MessageT));
           rcl_interfaces::msg::IntraProcessMessage ipm;
           ipm.publisher_id = intra_process_publisher_id_;
           ipm.message_sequence = message_seq;
          auto status = rcl_publish(&intra_process_publisher_handle_, &ipm);
          if (RCL_RET_PUBLISHER_INVALID == status) {
            rcl_reset_error();  // next call will reset error message if not context 
            if (rcl_publisher_is_valid_except_context(&intra_process_publisher_handle_)) {
              rcl_context_t * context = rcl_publisher_get_context(&intra_process_publisher_handle_);
              if (nullptr != context && !rcl_context_is_valid(context)) {
                // publisher is invalid due to context being shutdown 
                return;
               }
             }
           }
          if (RCL_RET_OK != status) {
             rclcpp::exceptions::throw_from_rcl_error(status, "failed to publish intra process message");
           }
         } else {
          // Always destroy the message, even if we don't consume it, for consistency. 
           msg.reset();
         }
       }
  
 

以及:


      #include <memory>
      void unique_func_ref(std::unique_ptr<int> & msg) {}
      void unique_func_value(std::unique_ptr<int> msg) {}
      int main(int argc, char ** argv)
      {
        std::unique_ptr<int> foo(new int);
        std::unique_ptr<int> bar(new int);
        unique_func_ref(foo);
        // does not compile
        // unique_func_value(bar);
        unique_func_value(std::move(bar));
        return 0;
      }
  
 

 


不学习现代C++,ROS1/2机器人编程连门都入不了啊………………

我自己从写C++的第一个hello world,到今天已经24年过去了,但还是水平菜如小白。

只能继续努力学习了。


智能指针C++11就已经引入了,让程序员不再需要关心手动释放内存。

(克服了传统C++,使用 newdelete 去 『手工操作(不能忘会内存泄漏的?)』对资源进行释放。)



      #include <iostream>
      #include <memory>
      void foo(std::shared_ptr<int> i)
      {
          (*i)++;
      }
      int main()
      {
         // auto pointer = new int(10); // illegal, no direct assignment
         // std::shared_ptr construction
         auto pointer = std::make_shared<int>(10);
         auto pointer2 = pointer;    // reference count + 1
         auto pointer3 = pointer;    // reference count + 1
         foo(pointer);
          std::cout << *pointer << std::endl; // 11
         int *p = pointer.get();             // does not increase reference count
          std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl;
          std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl;
          std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl;
          pointer2.reset();
          std::cout << "reset pointer2:" << std::endl;
          std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl;
          std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl;
          std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl;
          pointer3.reset();
          std::cout << "reset pointer3:" << std::endl;
          std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl;
          std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl;
          std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl;
         // std::cout << *pointer << std::endl; // reference count equals 0, illegal access
         // Before leaving the scope, the pointer is destructed and
         // the reference count is reduced to 0
         return 0;
      }
  
 

 



      #include <iostream>
      #include <memory>
      struct Foo {
         Foo()      { std::cout << "Foo::Foo" << std::endl;  }
          ~Foo()     { std::cout << "Foo::~Foo" << std::endl; }
         void foo() { std::cout << "Foo::foo" << std::endl;  }
      };
      void f(const Foo &) {
          std::cout << "f(const Foo&)" << std::endl;
      }
      int main() {
         std::unique_ptr<Foo> p1(std::make_unique<Foo>());
         // p1 is not empty, prints
         if (p1) p1->foo();
          {
             std::unique_ptr<Foo> p2(std::move(p1));
             // p2 is not empty, prints
             f(*p2);
             // p2 is not empty, prints
             if(p2) p2->foo();
             // p1 is empty, no prints
             if(p1) p1->foo();
              p1 = std::move(p2);
             // p2 is empty, no prints
             if(p2) p2->foo();
              std::cout << "p2 was destroyed" << std::endl;
          }
         // p1 is not empty, prints
         if (p1) p1->foo();
         // Foo instance will be destroyed when leaving the scope
      }
  
 

 

 



      #include <iostream>
      #include <memory>
      class A;
      class B;
      class A {
      public:
          std::shared_ptr<B> pointer;
          ~A() {
              std::cout << "A was destroyed" << std::endl;
          }
      };
      class B {
      public:
          std::shared_ptr<A> pointer;
          ~B() {
              std::cout << "B was destroyed" << std::endl;
          }
      };
      int main() {
          std::shared_ptr<A> a = std::make_shared<A>();
          std::shared_ptr<B> b = std::make_shared<B>();
          a->pointer = b;
          b->pointer = a;
         return 0;
      }
  
 


 

 

 

文章来源: zhangrelay.blog.csdn.net,作者:zhangrelay,版权归原作者所有,如需转载,请联系作者。

原文链接:zhangrelay.blog.csdn.net/article/details/124067964

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。