boost C++知识点(一)

2023-05-16

1 boost总览:
Boost.Any Boost.Any 提供了一个名为 boost::any 的数据类型,可以存放任意的类型。 例如,一个类型为 boost::any 的变量可以先存放一个 int 类型的值,然后替换为一个 std::string 类型的字符串。
Boost.Array TR1 Boost.Array 可以把 C++ 数组视同 C++ 标准的容器。
Boost.Asio TR2 Boost.Asio 可用于开发异步处理数据的应用,如网络应用。
Boost.Bimap Boost.Bimap 提供了一个名为 boost::bimap 的类,它类似于 std::map. 主要的差别在于 boost::bimap 可以同时从键和值进行搜索。
Boost.Bind TR1 Boost.Bind 是一种适配器,可以将函数作为模板参数,即使该函数的签名与模板参数不兼容。
Boost.Conversion Boost.Conversion 提供了三个转型操作符,分别执行向下转型、交叉转型,以及不同数字类型间的值转换。
Boost.DateTime Boost.DateTime 可用于以灵活的格式处理、读入和写出日期及时间值。
Boost.Exception Boost.Exception 可以在抛出的异常中加入额外的数据,以便在 catch 处理中提供更多的信息。 这有助于更容易地调试,以及对异常情况更好地作出反应。
Boost.Filesystem TR2 Boost.Filesystem 提供了一个类来处理路径信息,还包含了几个访问文件和目录的函数。
Boost.Format Boost.Format 以一个类型安全且可扩展的 boost::format 类替代了 std::printf() 函数。
Boost.Function TR1 Boost.Function 简化了函数指针的定义。
Boost.Interprocess Boost.Interprocess 允许多个应用通过共享内存以快速、高效的方式进行通信。
Boost.Lambda Boost.Lambda 可以定义匿名的函数。 代码被内联地声明和执行,避免了单独的函数调用。
Boost.Multiindex Boost.Multiindex 定义了一些新的容器,它们可以同时支持多个接口,如 std::vector 和 std::map 的接口。
Boost.NumericConversion Boost.NumericConversion 提供了一个转型操作符,可以安全地在不同的数字类型间进行值转换,不会生成上溢出或下溢出的条件。
Boost.PointerContainer Boost.PointerContainer 提供了专门为动态分配对象进行优化的容器。
Boost.Ref TR1 Boost.Ref 的适配器可以将不可复制对象的引用传给需要复制的函数。
Boost.Regex TR1 Boost.Regex 提供了通过正则表达式进行文本搜索的函数。
Boost.Serialization 通过 Boost.Serialization,对象可以被序列化,如保存在文件中,并在以后重新导入。
Boost.Signals Boost.Signal 是一个事件处理的框架,基于所谓的 signal/slot 概念。 函数与信号相关联并在信号被触发时自动被调用。
Boost.SmartPoiners TR1 Boost.SmartPoiners 提供了多个智能指针,简化了动态分配对象的管理。
Boost.Spirit Boost.Spirit 可以用类似于 EBNF (扩展巴科斯范式)的语法生成词法分析器。
Boost.StringAlgorithms Boost.StringAlgorithms 提供了多个独立的函数,以方便处理字符串。
Boost.System TR2 Boost.System 提供了一个处理系统相关或应用相关错误代码的框架。
Boost.Thread C++0x Boost.Thread 可用于开发多线程应用。
Boost.Tokenizer Boost.Tokenizer 可以对一个字符串的各个组件进行迭代。
Boost.Tuple TR1 Boost.Tuple 提供了泛化版的 std::pair,可以将任意数量的数据组在一起。
Boost.Unordered TR1 Boost.Unordered 扩展了 C++ 标准的容器,增加了boost::unordered_set 和 boost::unordered_map.
Boost.Variant Boost.Variant 可以定义多个数据类型,类似于 union, 将多个数据类型组在一起。 Boost.Variant 比 union 优胜的地方在于它可以使用类。

2 智能指针及数组、容器
2.1 boost智能指针:
1998年修订的第一版C++标准只提供了一种智能指针: std::auto_ptr 。 它基本上就像是个普通的指针: 通过地址来访问一个动态分配的对象。 std::auto_ptr 之所以被看作是智能指针,是因为它会在析构的时候调用 delete 操作符来自动释放所包含的对象。 当然这要求在初始化的时候,传给它一个由 new 操作符返回的对象的地址。 既然 std::auto_ptr 的析构函数会调用 delete 操作符,它所包含的对象的内存会确保释放掉。 这是智能指针的一个优点。

当和异常联系起来时这就更加重要了:没有 std::auto_ptr 这样的智能指针,每一个动态分配内存的函数都需要捕捉所有可能的异常,以确保在异常传递给函数的调用者之前将内存释放掉。 Boost C++ 库 Smart Pointers 提供了许多可以用在各种场合的智能指针。

智能指针的原理基于一个常见的习语叫做 RAII :资源申请即初始化。 智能指针只是这个习语的其中一例——当然是相当重要的一例。 智能指针确保在任何情况下,动态分配的内存都能得到正确释放,从而将开发人员从这项任务中解放了出来。 这包括程序因为异常而中断,原本用于释放内存的代码被跳过的场景。 用一个动态分配的对象的地址来初始化智能指针,在析构的时候释放内存,就确保了这一点。 因为析构函数总是会被执行的,这样所包含的内存也将总是会被释放。

无论何时,一定得有第二条指令来释放之前另一条指令所分配的资源时,RAII 都是适用的。 许多的 C++ 应用程序都需要动态管理内存,因而智能指针是一种很重要的 RAII 类型。 不过 RAII 本身是适用于许多其它场景的。

#include <windows.h> 

class windows_handle 
{ 
  public: 
    windows_handle(HANDLE h) 
      : handle_(h) 
    { 
    } 

    ~windows_handle() 
    { 
      CloseHandle(handle_); 
    } 

    HANDLE handle() const 
    { 
      return handle_; 
    } 

  private: 
    HANDLE handle_; 
}; 

int main() 
{ 
  windows_handle h(OpenProcess(PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId())); 
  SetPriorityClass(h.handle(), HIGH_PRIORITY_CLASS); 
} 

上面的例子中定义了一个名为 windows_handle 的类,它的析构函数调用了 CloseHandle() 函数。 这是一个 Windows API 函数,因而这个程序只能在 Windows 上运行。 在 Windows 上,许多资源在使用之前都要求打开。 这暗示着一旦资源不再使用之后就应该关闭。 windows_handle 类的机制能确保这一点。

windows_handle 类的实例以一个句柄来初始化。 Windows 使用句柄来唯一的标识资源。 比如说,OpenProcess() 函数返回一个 HANDLE 类型的句柄,通过该句柄可以访问当前系统中的进程。 在示例代码中,访问的是进程自己——换句话说就是应用程序本身。

我们通过这个返回的句柄提升了进程的优先级,这样它就能从调度器那里获得更多的 CPU 时间。 这里只是用于演示目的,并没什么实际的效应。 重要的一点是:通过 OpenProcess() 打开的资源不需要显示的调用 CloseHandle() 来关闭。 当然,应用程序终止时资源也会随之关闭。 然而,在更加复杂的应用程序里, windows_handle 类确保当一个资源不再使用时就能正确的关闭。 某个资源一旦离开了它的作用域——上例中 h 的作用域在 main() 函数的末尾——它的析构函数会被自动的调用,相应的资源也就释放掉了。

2.2 作用域指针
一个作用域指针独占一个动态分配的对象。 对应的类名为 boost::scoped_ptr,它的定义在 boost/scoped_ptr.hpp 中。 不像 std::auto_ptr,一个作用域指针不能传递它所包含的对象的所有权到另一个作用域指针。 一旦用一个地址来初始化,这个动态分配的对象将在析构阶段释放。

因为一个作用域指针只是简单保存和独占一个内存地址,所以 boost::scoped_ptr 的实现就要比 std::auto_ptr 简单。 在不需要所有权传递的时候应该优先使用 boost::scoped_ptr 。 在这些情况下,比起 std::auto_ptr 它是一个更好的选择,因为可以避免不经意间的所有权传递。

#include <boost/scoped_ptr.hpp> 

int main() 
{ 
  boost::scoped_ptr<int> i(new int); 
  *i = 1; 
  *i.get() = 2; 
  i.reset(new int); 
} 

一经初始化,智能指针 boost::scoped_ptr 所包含的对象,可以通过类似于普通指针的接口来访问。 这是因为重载了相关的操作符 operator*(),operator->() 和 operator bool() 。 此外,还有 get() 和 reset() 方法。 前者返回所含对象的地址,后者用一个新的对象来重新初始化智能指针。 在这种情况下,新创建的对象赋值之前会先自动释放所包含的对象。

boost::scoped_ptr 的析构函数中使用 delete 操作符来释放所包含的对象。 这对 boost::scoped_ptr 所包含的类型加上了一条重要的限制。 boost::scoped_ptr 不能用动态分配的数组来做初始化,因为这需要调用 delete[] 来释放。 在这种情况下,可以使用下面将要介绍的 boost:scoped_array 类。

2.3. 作用域数组:
作用域数组的使用方式与作用域指针相似。 关键不同在于,作用域数组的析构函数使用 delete[] 操作符来释放所包含的对象。 因为该操作符只能用于数组对象,所以作用域数组必须通过动态分配的数组来初始化。

对应的作用域数组类名为 boost::scoped_array,它的定义在 boost/scoped_array.hpp 里。

#include <boost/scoped_array.hpp> 

int main() 
{ 
  boost::scoped_array<int> i(new int[2]); 
  *i.get() = 1; 
  i[1] = 2; 
  i.reset(new int[3]); 
} 

boost:scoped_array 类重载了操作符 operator 和 operator bool()。 可以通过 operator 操作符访问数组中特定的元素,于是 boost::scoped_array 类型对象的行为就酷似它所含的数组。

正如 boost::scoped_ptr 那样, boost:scoped_array 也提供了 get() 和 reset() 方法,用来返回和重新初始化所含对象的地址。

2.4. 共享指针:
这是使用率最高的智能指针,但是 C++ 标准的第一版中缺少这种指针。 它已经作为技术报告1(TR 1)的一部分被添加到标准里了。 如果开发环境支持的话,可以使用 memory 中定义的 std::shared_ptr。 在 Boost C++ 库里,这个智能指针命名为 boost::shared_ptr,定义在 boost/shared_ptr.hpp 里。

智能指针 boost::shared_ptr 基本上类似于 boost::scoped_ptr。 关键不同之处在于 boost::shared_ptr 不一定要独占一个对象。 它可以和其他 boost::shared_ptr 类型的智能指针共享所有权。 在这种情况下,当引用对象的最后一个智能指针销毁后,对象才会被释放。

因为所有权可以在 boost::shared_ptr 之间共享,任何一个共享指针都可以被复制,这跟 boost::scoped_ptr 是不同的。 这样就可以在标准容器里存储智能指针了——你不能在标准容器中存储 std::auto_ptr,因为它们在拷贝的时候传递了所有权。

#include <boost/shared_ptr.hpp> 
#include <vector> 

int main() 
{ 
  std::vector<boost::shared_ptr<int> > v; 
  v.push_back(boost::shared_ptr<int>(new int(1))); 
  v.push_back(boost::shared_ptr<int>(new int(2))); 
} 

多亏了有 boost::shared_ptr,我们才能像上例中展示的那样,在标准容器中安全的使用动态分配的对象。 因为 boost::shared_ptr 能够共享它所含对象的所有权,所以保存在容器中的拷贝(包括容器在需要时额外创建的拷贝)都是和原件相同的。如前所述,std::auto_ptr做不到这一点,所以绝对不应该在容器中保存它们。

类似于 boost::scoped_ptr, boost::shared_ptr 类重载了以下这些操作符:operator*(),operator->() 和 operator bool()。另外还有 get() 和 reset() 函数来获取和重新初始化所包含的对象的地址。

2.5. 共享数组:
共享数组的行为类似于共享指针。 关键不同在于共享数组在析构时,默认使用 delete[] 操作符来释放所含的对象。 因为这个操作符只能用于数组对象,共享数组必须通过动态分配的数组的地址来初始化。

共享数组对应的类型是 boost::shared_array,它的定义在 boost/shared_array.hpp 里。

#include <boost/shared_array.hpp> 
#include <iostream> 

int main() 
{ 
  boost::shared_array<int> i1(new int[2]); 
  boost::shared_array<int> i2(i1); 
  i1[0] = 1; 
  std::cout << i2[0] << std::endl; 
} 

就像共享指针那样,所含对象的所有权可以跟其他共享数组来共享。 这个例子中定义了2个变量 i1 和 i2,它们引用到同一个动态分配的数组。i1 通过 operator 操作符保存了一个整数1——这个整数可以被 i2 引用,比如打印到标准输出。

和本章中所有的智能指针一样,boost::shared_array 也同样提供了 get() 和 reset() 方法。 另外还重载了 operator bool()。

2.6. 弱指针
到目前为止介绍的各种智能指针都能在不同的场合下独立使用。 相反,弱指针只有在配合共享指针一起使用时才有意义。 弱指针 boost::weak_ptr 的定义在 boost/weak_ptr.hpp 里。

#include <windows.h> 
#include <boost/shared_ptr.hpp> 
#include <boost/weak_ptr.hpp> 
#include <iostream> 

DWORD WINAPI reset(LPVOID p) 
{ 
  boost::shared_ptr<int> *sh = static_cast<boost::shared_ptr<int>*>(p); 
  sh->reset(); 
  return 0; 
} 

DWORD WINAPI print(LPVOID p) 
{ 
  boost::weak_ptr<int> *w = static_cast<boost::weak_ptr<int>*>(p); 
  boost::shared_ptr<int> sh = w->lock(); 
  if (sh) 
    std::cout << *sh << std::endl; 
  return 0; 
} 

int main() 
{ 
  boost::shared_ptr<int> sh(new int(99)); 
  boost::weak_ptr<int> w(sh); 
  HANDLE threads[2]; 
  threads[0] = CreateThread(0, 0, reset, &sh, 0, 0); 
  threads[1] = CreateThread(0, 0, print, &w, 0, 0); 
  WaitForMultipleObjects(2, threads, TRUE, INFINITE); 
} 

boost::weak_ptr 必定总是通过 boost::shared_ptr 来初始化的。一旦初始化之后,它基本上只提供一个有用的方法: lock()。此方法返回的boost::shared_ptr 与用来初始化弱指针的共享指针共享所有权。 如果这个共享指针不含有任何对象,返回的共享指针也将是空的。

当函数需要一个由共享指针所管理的对象,而这个对象的生存期又不依赖于这个函数时,就可以使用弱指针。 只要程序中还有一个共享指针掌管着这个对象,函数就可以使用该对象。 如果共享指针复位了,就算函数里能得到一个共享指针,对象也不存在了。

上例的 main() 函数中,通过 Windows API 创建了2个线程。 于是乎,该例只能在 Windows 平台上编译运行。

第一个线程函数 reset() 的参数是一个共享指针的地址。 第二个线程函数 print() 的参数是一个弱指针的地址。 这个弱指针是之前通过共享指针初始化的。

一旦程序启动之后,reset() 和 print() 就都开始执行了。 不过执行顺序是不确定的。 这就导致了一个潜在的问题:reset() 线程在销毁对象的时候print() 线程可能正在访问它。

通过调用弱指针的 lock() 函数可以解决这个问题:如果对象存在,那么 lock() 函数返回的共享指针指向这个合法的对象。否则,返回的共享指针被设置为0,这等价于标准的null指针。

弱指针本身对于对象的生存期没有任何影响。 lock() 返回一个共享指针,print() 函数就可以安全的访问对象了。 这就保证了——即使另一个线程要释放对象——由于我们有返回的共享指针,对象依然存在。

2.8. 指针容器
在你见过 Boost C++ 库的各种智能指针之后,应该能够编写安全的代码,来使用动态分配的对象和数组。多数时候,这些对象要存储在容器里——如上所述——使用 boost::shared_ptr 和 boost::shared_array 这就相当简单了。

#include <boost/shared_ptr.hpp> 
#include <vector> 

int main() 
{ 
  std::vector<boost::shared_ptr<int> > v; 
  v.push_back(boost::shared_ptr<int>(new int(1))); 
  v.push_back(boost::shared_ptr<int>(new int(2))); 
} 

上面例子中的代码当然是正确的,智能指针确实可以这样用,然而因为某些原因,实际情况中并不这么用。 第一,反复声明 boost::shared_ptr 需要更多的输入。 其次,将 boost::shared_ptr 拷进,拷出,或者在容器内部做拷贝,需要频繁的增加或者减少内部引用计数,这肯定效率不高。 由于这些原因,Boost C++ 库提供了 指针容器 专门用来管理动态分配的对象。

#include <boost/ptr_container/ptr_vector.hpp> 

int main() 
{ 
  boost::ptr_vector<int> v; 
  v.push_back(new int(1)); 
  v.push_back(new int(2)); 
} 

boost::ptr_vector 类的定义在 boost/ptr_container/ptr_vector.hpp 里,它跟前一个例子中用 boost::shared_ptr 模板参数来初始化的容器具有相同的工作方式。 boost::ptr_vector 专门用于动态分配的对象,它使用起来更容易也更高效。 boost::ptr_vector 独占它所包含的对象,因而容器之外的共享指针不能共享所有权,这跟 std::vector<boost::shared_ptr > 相反。

除了 boost::ptr_vector 之外,专门用于管理动态分配对象的容器还包括:boost::ptr_deque, boost::ptr_list, boost::ptr_set, boost::ptr_map, boost::ptr_unordered_set 和 boost::ptr_unordered_map。这些容器等价于C++标准里提供的那些。最后两个容器对应于std::unordered_set 和 std::unordered_map,它们作为技术报告1的一部分加入 C++ 标准。 如果所使用的 C++ 标准实现不支持技术报告1的话,还可以使用 Boost C++ 库里实现的 boost::unordered_set 和 boost::unordered_map。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

boost C++知识点(一) 的相关文章

  • 人工智能会取代程序员吗?

    多亏了人工智能 xff08 AI xff09 xff0c 软件将在未来自行编写 至少 xff0c 这就是谷歌首席执行官桑达尔 皮查伊 xff08 Sundar Pichai xff09 对软件开发未来的看法 他是对的 xff01 这并不能使
  • 人工智能和5G在无人机技术中的作用

    技术为我们提供了许多引人入胜的设备和发明 xff0c 无人机就是其中之一 无人机 xff0c 在技术术语中也称为无人机 xff08 UAV xff09 xff0c 自2007年首次出现以来越来越受欢迎 这些小工具最初是手动和远程控制的 无人
  • 惠普暗影精灵笔记本开机自动打开小键盘,冷热启动均支持

  • STM32F4 使用结构体配置功能

    1 IIC配置 void IIC Mode Config void I2C InitTypeDef I2C InitStructure I2C InitStructure I2C Mode 61 I2C Mode I2C IIC模式 I2C
  • 执行 sudo apt-get update 报错:仓库 xxx 没有release文件 / 不再含有release文件

    输入命令 sudo apt get update 报错 这里可以看到有两个问题 xff0c 一个是 ubuntu自己的源连不上了 第二三个红框框 xff0c 一个是 vmware 这个软件 第一个红框框 首先解决第一个问题 archive
  • C++ 发送HTTP请求

    HTTPRequest HTTPRequest是一个用于发出HTTP请求的单头C 43 43 库 您可以将它包含在项目中并使用它 HTTPRequest在macOS Windows Haiku BSD和GNU Linux上进行了测试 xff
  • 小程序、公众号开发报code been used(40163)或invalid code(40029)错误,解决方案--之--搞清楚微信的登录机制,保存登录状态!!!

    x1f4d6 前言 做微信小程序或公众号开发 xff0c 有时我们为了管理用户 xff0c 需要获取用户的openid xff0c unionId等信息 这时会用到微信提供的接口 xff1a code2Session code2Sessio
  • 使用git在vscode中进行版本控制

    版本控制是一件非常cool的事 xff0c 可以将我们的代码按照版本存储 1 首先我们选择一个版本控制工具 xff0c 这里我们选择git xff0c 点击下载安装 xff0c 安装时选择vscode编辑器 2 安装好了之后打开vscode
  • 2.3.1 参数服务器理论模型

    ROS入门 2 3 1 参数服务器理论模型 ROS入门 理论与实践 视频教程镇楼 参数服务器实现是最为简单的 xff0c 该模型如下图所示 该模型中涉及到三个角色 ROS Master 管理者 Talker 参数设置者 Listener 参
  • 4.6.3 编码设置参数

    ROS入门 4 6 3 编码设置参数 ROS入门 理论与实践 视频教程镇楼 编码的方式可以更方便的设置 全局 相对与私有参数 1 C 43 43 实现 在 C 43 43 中 xff0c 可以使用 ros param 或者 ros Node
  • 5.1 TF坐标变换

    ROS入门 5 1 TF坐标变换 ROS入门 理论与实践 视频教程镇楼 机器人系统上 xff0c 有多个传感器 xff0c 如激光雷达 摄像头等 xff0c 有的传感器是可以感知机器人周边的物体方位 或者称之为 坐标 xff0c 横向 纵向
  • 10.1.3 action通信自定义action文件调用(Python)

    ROS入门 10 1 3 action通信自定义action文件调用 Python ROS入门 理论与实践 视频教程镇楼 需求 创建两个ROS 节点 xff0c 服务器和客户端 xff0c 客户端可以向服务器发送目标数据N 一个整型数据 服
  • rosdep

    rosdep 初始化时异常解决方案 rosdep 初始化时异常解决 视频教程 安装构建依赖 在 noetic 最初发布时 xff0c 和其他历史版本稍有差异的是 没有安装构建依赖这一步骤 随着 noetic 不断完善 xff0c 官方补齐了
  • springboot应用集成prometheus监控

    环境参数 xff1a 运行命令 xff1a 1 uname xff0d a xff08 Linux查看版本当前操作系统内核信息 xff09 2 cat proc version xff08 Linux查看当前操作系统版本信息 xff09 3
  • [NVIDIA Jetson Xavier Nx]从刷机烧录到环境配置 记录

    目录 前言一 开机烧录二 环境配置Cuda环境变量配置更新源python环境配置安装Jtop 内存 CPU GPU等等资源监视工具 前言 对进行NVIDIA Jetson Xavier Nx环境配置进行记录 一 开机烧录 参考下面的博客 x
  • 最近处理的报错 -DCMAKE_BUILD_TYPE=Debug

    1 error 39 nullptr 39 was not declared in this scope 解决方法 使用的是QTcreator的pro文件 然后缺少相应关于c 43 43 11的设置 点pro文件中加载的东西如下 QMAKE
  • Halcon 单相机标定

    原文链接 xff1a https blog csdn net weixin 43197380 article details 90438976 comments 13104885 一 理论 为什么要进行单相机标定 xff1f 广义 xff1
  • 将图片嵌入Markdown文档

    将图片嵌入Markdown文档中是一个比较难受的事情 一般大家都会将图片存入本地某个路径或者网络存储空间 xff0c 使用URL链接的形式插入图片 image url to image 将图片放到本地的时候如果想将文档分享给朋友或者换台电脑
  • 自定义的串口通信协议

    自定义的通信协议 自定义一主多从串口通讯 1硬件基础两个从机的 Tx 是相互连接的 xff0c 导致一个从机在需要发送数据时发不出去了 协议思路数据包封装和解封装 树莓派python串口的使用注意更改树莓派串口设备驱动关闭控制台功能pyth
  • Linux串口驱动程序(4)-数据发送

    1 tty数据发送调用关系 怎么样才能找到发送数据所使用的函数呢 xff1f 打开uart register driver函数 xff0c 找到里面的tty register driver xff0c 转到定义 xff0c 这里调用了tty

随机推荐

  • TF 错误:InvalidArgumentError (see above for traceback): Reduction axis 0 is empty in shape [ ]

    Tensorflow python framework errors impl InvalidArgumentError Reduction axis 0 is empty in shape 0 100 Node ArgMax 61 Arg
  • Raspbian安装ROS系统Kinectic|树莓派4B安装ros使用OpenCV(全流程)

    前言 树莓派4B最高拥有4Gb的RAM xff0c 对于承担图像处理任务的嵌入式设计是个性价比很高的选择 众所周知 xff0c ROS系统对Ubuntu系统最友好 xff0c 但是由于树莓派4暂时还无法使用Ubuntu MATE xff0c
  • Ubuntu设置屏幕分辨率及屏幕翻转

    首发于 xff1a yuany3721的WordPress Version Ubuntu 18 04 6 LTS 使用xrandr查看屏幕信息 xrandr Screen 0 minimum 320 x 200 current 1920 x
  • 用美图秀秀换证件照背景颜色

    xff08 JDD KK 原创 xff09 问题描述 xff1a 不会PS xff0c 也没有各种会员 xff0c 怎么为了应急去换证件照背景 xff1f xff08 此方法有局限 xff0c 且质量一般 xff0c 只为应急 xff09
  • 让自己写的程序也有api

    当我们在学习的时候 xff0c 有时候看到别人的api会感觉到蛮高大上的 其实他们的api并不是他们在写完程序之后 xff0c 通过键盘录入的 xff0c 而是通过工具来生生成的 因此我们完全有机会打造属于自己的api api的作用 1 便
  • 记录使用gitlab实现Docker自动化部署

    目录 前言 一 gitlab runner docker安装 二 gitlab runner的注册与使用 1 注册 2 gitlab ci yml 脚本编写 总结 前言 前面搭建了gitlab与harbor xff0c 现在就使用它们来实现
  • ros::ok()

    ros ok 在以下几种情况下会返回false xff1a 按下Ctrl C时 我们被一个同名同姓的节点从网络中踢出 ros shutdown 被应用程序的另一部分调用 所有的ros NodeHandles都被销毁了 一旦ros ok 返回
  • 小觅深度相机标准版 ROS使用

    只写运行起来 xff0c 具体实例运行方法在对应的实例中 系统 xff1a ubuntu16 04 1 安装SDK 下载SDK驱动并解压 xff1a https github com slightech MYNT EYE S SDK 看RE
  • 移动机器人(四)四轴飞行器

    四轴飞行控制原理 四轴飞行器在空间上有6个自由度 xff0c 分别是沿3个坐标轴进行平动和转动 xff0c 通过对四个旋翼的转速控制来实现 xff0c 6个自由度方向的运动姿态分别为 xff1a 垂直升降 俯仰角度 前后飞行 横滚角度 左右
  • (二) 使用vscode

    1 在拉代码过程中 xff0c 使用代码对比工具 左侧有个分支工具 xff0c 点击左侧栏中某个文件 xff0c 右侧出现两栏 以102行为例 xff0c 红色部分为代码改动之前显示 xff0c 右侧绿色部分为代码改动之后显示 2 文件工具
  • 30个实用VSCode 插件,让你的开发效率倍增!

    1 Image preview 通过此插件 xff0c 当鼠标悬浮在图片的链接上时 xff0c 可以实时预览该图片 xff0c 除此之外 xff0c 还可以看到图片的大小和分辨率 2 Auto Rename Tag 使用该插件 xff0c
  • OpenCV 4.5.0+conrtrib 已编译完成(附下载链接)

    OpenCV 4 5 0 43 conrtrib 已编译完成 xff0c 包含编译源码 平台 Windows 43 VS2015 百度网盘链接 提取密码 xff1a rdgh 源码下载 OpenCV源码下载链接推荐 xff08 包含匹配的c
  • 第一篇综述-无人车简介

    综述 无人车简介 xff08 1 xff09 1 1无人车的定义以及分级 1 2无人车的发展历程 参考链接 原文链接 xff1a https blog csdn net thomashtq article details 81161018
  • 在C#中使用Intptr究竟需不需要释放?

    只有是用Marshal 申请的 xff08 AllocHGlobal xff09 这种需要释放 xff1b 对于使用PInvoke 返回的IntPtr不用释放 xff1b 简单来说 xff0c 这个东西是你创建出来的你就得负责回收 xff0
  • .NET中Invoke和BeginInvoke

    在 NET中 xff0c 固定必须主线程才能操作UI界面 xff0c 如果在非主线程中强行对UI界面赋值 xff0c 则会报错 xff0c 跨线程操作UI 是不允许的 xff0c 需要使用Invoke或BeginInvoke xff0c 关
  • php 跨域解决方案

    设置允许访问的域名 xff1a 1 允许全部的域名访问 span class token function header span span class token punctuation span span class token str
  • WPF之转换器

    WPF是一个数据驱动模式 xff0c 开发中都是以数据为中心 xff0c WPF具有数据绑定机制 xff0c 数据有变化时 xff0c 会通知UI进行更新 WPF用的是MVVM模式 MVVM是Model View ViewModel xff
  • CS程序自动更新和手动更新的技术实现

    1 程序启动时检查更新 xff0c 如果可以更新 xff0c 则判断是否为强制性更新 xff0c 如果是则直接强制更新 xff0c 不是则不处理 xff0c 转为到程序更新模块中手动处理 xff0c 这是更新最基本的原理 检查更新 priv
  • 用MATLAB将矩阵数据写入txt文件中,打开乱码原因

    MATLAB将数据写入txt文件中乱码的原因 xff0c 是将数据按照二进制文件写入txt文件 xff0c 所以打开会出现乱码的情况 xff0c 只需要把 fid1 61 fopen 39 piture txt 39 39 w 39 换成
  • boost C++知识点(一)

    1 boost总览 xff1a Boost Any Boost Any 提供了一个名为 boost any 的数据类型 xff0c 可以存放任意的类型 例如 xff0c 一个类型为 boost any 的变量可以先存放一个 int 类型的值