《条目十六》如何将vector和string的数据传给遗留的API

优秀的代码是可以延续的,所以并非所有的代码都是重构的,而且有时候重构会对整个系统影响较大,投入巨大,得不偿失。然而,也不必为了系统的稳定而抛弃先进和方便的技术。

正如如果你想在遗留的老代码中想传vectorstring给形参是数组的接口,那么可以按以下的方法做:

接口:void dosomething(const char* ptr, size_t size);

vectordosomething接口方法:

  • 1、&vec[0]———————-可行
  • 2、vec.begin()—————不正确
  • 3、&*vec.begin()————可行

方法1是ok,这是因为vector在内存上是连续分布的,和数组的内存分布是一致的,所以对vector的首元素取地址就是获得vector分配内存的首地址,通过首地址就可以得到连续的整块内存。

但是需要注意的是,vecto可能为空的情况,这样传参过去,形参是null, size为0,这样是错误的。可以在调用函数的时候就判断vector是否非空。

if(!vec.empty())
{
dosomething(&vev[0], vec.size());
}

这才是标准的做法。

方法2是不正确的,这样做可能是因为有人觉得vec.begin()得到的是指向vector容器的首地址的迭代器,就相当于是容器的地址。这里有个误区,迭代器不是指针,二者并非是等价的。

方法3是正确的,对比方法2方法3先取得容器的首个元素的迭代器,然后解引用获得首个元素,再对其取地址。这样就等同于&vec[0]。

stringdosomething接口方法:

  • 1、s.c_str()——————正确
  • 2、&s[0]——————————错误
  • 3、&*vec.begin()————错误

string传参给char*需要注意了,由于string的实现是多种多样的,string对象的首个地址并非一定是字符串值的地址,详细的请看条目15的分析。所以直接传递string的首元素的地址过去都是不正确,不管是直接对首元素取地址还是对取迭代器起始位置的解引用的地址,统统都不正确。

正确的做法是方法1,直接调用string.c_str()接口,直接帮我们实现string传参给char*

通过上面的分析知道,vector可以很好的帮助我们实现容器传参给char*的目的。从这可以展开来,可以把所有的容器先转换为vector,然后再传递给以char*的形参的老接口

但是在传递容器类型给以指针为形参的遗留API时需要注意,基本是传递const类型的,因为在函数内部对外部容器新增元素,容器是不知道它的size会发生变化的,因为不是通过容器本身改变新增元素,内部没有对size自增的,所以size真正没有改变。所以这样会造成容器数据的混乱,发生未定义行为。

上面举例子的都是以char*为例子,真正情况下任何的基本类型的指针都是可以的。

看下面的例子:

void dosomething(const int* ptr, size_t size);

set<int> set;
for(int i = 0; i < 10; ++i)
{
set.insert(i);
}
vector<int> vec1(set.begin(), set.end());
if(!vec1.empty())
{
dosomething(&vec1[0], vec1.size());
} list<int> list;
for(int i = 0; i < 10; ++i)
{
list.push_back(i);
}
vector<int> vec2(list.begin(), list.end());
if(!vec2.empty())
{
dosomething(&vec2[0], vec2.size());
}

《条目十六》如何将vector和string的数据传给遗留的API的更多相关文章

  1. 条目十三《尽量使用vector和string来代替使用数组》

    条目十三<尽量使用vector和string来代替使用数组> 数组在现代编程语言中基本都存在,应用可谓广泛,不可或缺,虽然在一些语言中(go)有切片等数据结构,但是数组还是存在的. 但是在 ...

  2. 【S16】了解如何把vector和string数据传给旧的API

    1.尽量使用vector和string替换数组,但是老的代码还是使用数组.如果老的接口期望是数组,怎么办? 需要把vector和string,暴露出数组接口,也就是第一个元素的地址. 2.考虑方法Do ...

  3. robotframework的学习笔记(十六)----robotframework标准库String

    官方文档:http://robotframework.org/robotframework/latest/libraries/String.html Introduction A test libra ...

  4. (十六)java中的String

    String:字符串类型,是java中最常用的引用类型,String是不可变的,java.lang.String是由final修饰,此类不可被继承.     String是不可变的,指的是字符串一旦创 ...

  5. 【第十六章】 springboot + OKhttp + String.format

    模拟浏览器向服务器发送请求四种方式: jdk原生的Http包下的一些类 httpclient(比较原始,不怎么用了):第一章 HttpClient的使用 Okhttp(好用,推荐) retrofit( ...

  6. kuangbin专题十六 KMP&&扩展KMP HDU3347 String Problem(最小最大表示法+kmp)

    Give you a string with length N, you can generate N strings by left shifts. For example let consider ...

  7. leecode第十六题(最接近的三数之和)

    class Solution { public: void quick_order(vector<int>& num, int star, int en)//快排 { int st ...

  8. LeetCode第十六题-找出数组中三数之和最接近目标值的答案

    3Sum Closest 问题简介: 给定n个整数的数组nums和整数目标,在nums中找到三个整数,使得总和最接近目标,返回三个整数的总和,可以假设每个输入都只有一个解决方案 举例: 给定数组:nu ...

  9. JAVA之旅(十六)——String类,String常用方法,获取,判断,转换,替换,切割,子串,大小写转换,去除空格,比较

    JAVA之旅(十六)--String类,String常用方法,获取,判断,转换,替换,切割,子串,大小写转换,去除空格,比较 过节耽误了几天,我们继续JAVA之旅 一.String概述 String时 ...

随机推荐

  1. Pascal三角形

    Pascal算法呢,很简单,因为有了推导公式nCr,而当我们刚刚接触一个事物时,面对要解决的问题,归纳分析得到规律,再通过编程,控制流程,对象,语言,方法,属性得到我们想要的结果.如果这次不是PAsc ...

  2. winform 如何正确的获取窗体的标题栏高度

    最近我需要知道鼠标在一个控件里的相对位置,鼠标相对于屏幕的位置我是可以知道的,所以只要得到控件相对于屏幕的位置,就可以算出鼠标相对于控件的位置了 但是发现有误差 后来经过测试是由于窗体的标题栏高度导致 ...

  3. Python学习笔记_Python向Excel写入数据

    实验环境 1.OS:Win 10 64位 2.Python 3.7 3.如果没有安装xlwt库,则安装:pip install xlwt 下面是从网上找到的一段代码,网上这段代码,看首行注释行,是在L ...

  4. Debian上SCST的设置

    一)创建SCST,无infiniband支持 1:载入最小化支持 #aptitude install build-essentials linux-headers checkinstall #wget ...

  5. BOOL运算符号(从C#入门经典第五版中摘录)

    只总结自己觉得难的哈: (1) var1=!var2;    //(非) (2) var1=var2&var3;    //(与) (3)var1=var2|var3;    //(或) (4 ...

  6. xgboost 调参 !

    https://jessesw.com/XG-Boost/ http://blog.csdn.net/u010414589/article/details/51153310

  7. activex打包

    http://www.cnblogs.com/weiwin/p/4493835.html activeX 打包   原文 http://www.docin.com/p-409284488.html C ...

  8. hdu 2519 新生晚会 (求排列组合时容易溢出)

    #include<stdio.h> #include<algorithm> using namespace std; void cal(int n,int m) { ; m=m ...

  9. MongoDB整理笔记のMapReduce

    MongDB的MapReduce相当于MySQL中的“group by”,所以在MongoDB上使用Map/Reduce进行并行“统计”很容易. 使用MapReduce要实现两个函数Map函数和Red ...

  10. C#字符串string的常用使用方法(转载)

    1--->字符串的声明: 1.string s=new string(char[] arr)     //根据一个字符数组声明字符串,即将字符字组转化为字符串. 2.string s=new s ...