《条目十六》如何将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. django 基于正则表达式的url

    方式一: urls.py from mytest import views urlpatterns = [ url(r'^index-(\d+)-(\d+).html', views.Index.as ...

  2. Bypassing iPhone Code Signatures

    [Bypassing iPhone Code Signatures] Starting with the recent beta releases of the iPhoneOS, Apple has ...

  3. SpringMVC总结四:拦截器简单介绍

    首先要说一下HandlerExecutionChain: HandlerExecutionChain是一个执行链,当用户的请求到达DispatcherServlet的时候,DispatcherServ ...

  4. zookeeper java api(使用java代码操作zookeeper)

    1 导入相关的pom依赖 <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId&g ...

  5. java基础之匿名内部类

    内部类: 概述: 类里边还有一个类, 里边那个类叫内部类, 外边那个类叫外部类. 分类: 成员内部类: 定义在成员位置的内部类. 局部内部类: 定义在局部位置的内部类. 格式: new 类名或者接口名 ...

  6. 值得一做》关于并查集的进化题目 BZOJ1015(BZOJ第一页计划)(normal-)

    这道题和以前做过的一道经典的洪水冲桥问题很像,主要做法是逆向思维.(BZOJ第10道非SB题纪念) 先给出题目 Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者 ...

  7. 724. Find Pivot Index 找到中轴下标

    [抄题]: Given an array of integers nums, write a method that returns the "pivot" index of th ...

  8. 453D Little Pony and Elements of Harmony

    传送门 分析 我们可以将所有的b[i^j]直接对应到b[f(i^j)]上 于是显然可以fwt 我们对b进行t次fwt之后直接将答案与e0卷起来即可 注意由于模数不确定,我们可以将模数扩大$2^m$然后 ...

  9. p2148 [SDOI2009]E&D

    传送门 分析 https://www.luogu.org/blog/flashblog/solution-p2148 代码 #include<bits/stdc++.h> using na ...

  10. Luogu 1580 [NOIP2016] 换教室

    先用Floyed做亮点之间的最短路,设计dp,记dp[i][j][0]为到第i节课,换了j次课,当前有没有换课达到的期望耗费体力最小值 方程(太长了还是看代码吧):dp[i][j][0]<-dp ...