zoukankan      html  css  js  c++  java
  • Effective_STL 学习笔记(十六) 如何将 vector 和 string 的数据传给遗留的API

    已经存在的遗留的 C 风格 API 接受的是数组和 char* 指针,这样的 API 函数还将会存在很长时间,如果我们要有效使用 STL 的话,就必须和它们和平共处。

    如果有一个 vector 对象 v,而你需要一个指向 v 中数据的指针,以使得它可以被当作一个数组,只要 &v[0] 就可以了。对于 string 对象 s,相应的使用 s.c_str()

    1   void doSomething( const int* pInts, size_t numInts );
    2   doSomething( &v[0], v.size() );
    3   void doSomething( const char* pString ); 4   doSomething( s.c_str() );

    对于 vector 使用不要使用 v.begin() 代替 &v[0],v.begin() 是迭代器,不是指针,一定要使用的话,键入&*v.begin()

    string 的成员函数 c_str() 返回一个按 C 风格设计的指针,指向 string 的值

    两种形式下,指针都被传递为指向 const 的指针

    1     void doSomething( const int* pInts, size_t numInts );
    2     void doSomething( const cahr* pString );

    vector 和 string 只能传给只读取而不修改它的API,对于 string 来说是唯一可做的,对于 vector 相对灵活一点。

    如果想用 C 风格API返回的元素初始化一个 vector,可以利用 vector 和数组潜在的内存分配兼容性将存储 vector 的元素空间传给API函数:

    1   // C API:此函数需要一个指向数组的指针,数组最多有 arraySize 个 double
    2   // 而且会对数组写入数据。它返回写入的 double 数,不会大于 arraySize
    3   size_t fillArray( double* pArray, size_t arraySize ); 4   vector<double> vd( maxNumDoubles );        // 建立一个 vector,大小是 maxNumDoubles 5   vd.resize( fillArray( &vd[0], vd.size() ) );  // 写入vd,然后调整 vd 的大小为fillArray

    这个技巧只能工作于vector,因为只有vector承诺了与数组具有相同的潜在内存分布。

    如果想用C风格 API 初始化 string 对象,只要让 API 将数据放入一个 vector<char>,然后再从 vector 中将数据拷到 string:

    1   // C API:此函数需要一个指向数组的指针,数组最多有 arraySize 个 char
    2   // 而且会对数组写入数据。它返回写入的 char 数,不会大于 arraySize
    3   size_t fillString( char* pArray, size_t arraySize );
    4   vector<char> vc( maxNumChars );        // 建立一个 vector
    5   size_t charsWritten = fillString( &vc[0], vc.size() );// 让 fillString 把数据写入 vc
    6   string s( vc.begin(), vc.end() + charsWritten );    // 从 vc 通过范围构造函数拷贝数据到s

    事实上,让 C 风格 API 把数据放入一个 vector,然后拷到你实际想要的 STL 容器中总是有效的:

    1   size_t fillString( double* pArray, size_t arraySize );
    2   vector<double> vd( maxNumDoubles ); 
    3   vd.resize( fillArray( &vd[0], vd.size() ) );
    4 
    5   deque<double> d( vd.begin(), vd.end() );  // 拷贝数据到 deque
    6   list<double> d( vd.begin(), vd.end() );   // 拷贝数据到 list
    7   set<double> d( vd.begin(), vd.end() );   // 拷贝数据到 set

    此外,对于 vector 和 string 以外的 STL 容器如何将他们的数据传给 C 风格 API。只要将容器的每个数据拷到 vector,然后将它们传给API:

      void doSomething( const int* pints, size_t numInts );
      set<int> intSet;
      . . .
      vector<int> v( intSet.begin(), intSet.end() );  // 拷贝 set 数据到 vector
      if( !v.empty() )              
        doSomething( &v[0], v.size() );    // 传递数据到 API
  • 相关阅读:
    微信小程序 | 小程序的转发问题
    开发辅助 | 前端开发工程师必懂的 UI 知识
    微信小程序 | canvas绘图
    服务端 | Linux 学习总结 (一)
    移动端适配 | 适配方案总结
    开发工具 | 利用 deployd 搭建个人博客
    1.10 组织好代码文件,要有“用户思维”
    1.9 组织好代码段,让人对它“一见钟情”
    《计算机是怎样跑起来的》读书笔记(1)
    实用网站收藏
  • 原文地址:https://www.cnblogs.com/kidycharon/p/10009981.html
Copyright © 2011-2022 走看看