美文网首页
Effective STL 第16条

Effective STL 第16条

作者: 懒生活 | 来源:发表于2022-09-18 23:14 被阅读0次

如何获取vector string的原始资源.

通常的做法

vector v; string s;
&v[0] 就可以获取原始资源的指针
s.c_str()就可以获取原始字符串数组的指针
因为c++标准要求vector中的元素按顺序存储在连续的空间中,所以定位找到第一个元素指针就能找到全部的元素.但问题是如果v是空的. 那么&v[0] 将返回一个野指针. 所以在使用&v[0]前要确保(!v.empty())
那问题是对于string类型的s,为什么不能通过&s[0]来获取头指针呢.
个人理解: 因为c++标准没有规定string中的元素一定是按顺序联系存放的. 所以有可能&s[0]取出的指针和&s[1]取出的指针不一定是挨着的. 但是string标准会提供一个c_str()函数,这个函数能够返回一个指针,指向连续的数据空间. 如果string的实现是不连续存放的,那么他的c_str()函数接口就会想办法复制一份数据到连续空间,并返回指针.

注意不能通过string的raw指针去修改数据

c_str()返回的指针是只读,不可写. 就上上面描述的,有可能string的实现是非连续存储. 当调用c_str()的时候, 是把非连续存储的数据放到了一份连续空间供你查看, 这个空间只是临时生成的.并不是string维护数据真正的地方.对他修改是没有意义的, string内部的维护信息并不认可这样的改动.如果用这种方式修改数据, 后续string的size, append等操作都会异常.

不要通过vector的raw指针去修改数据

一样的如果你通过raw指针越界了,此时的vector并不会帮你去扩容. 此时的越界会导致程序异常. 即使不越界, 你通过raw指针新加了一个数据,vector也不知道,他的size还是原来的大小.

如何把一个数组转化成vector

可以充分利用vector和数组都保证连续存储的特征.

int arrayInt[100] = { 0, };
int main()
{
    for (int i = 0; i < 100; i++)
        arrayInt[i] = i;
    vector<int> vecInt;
    vecInt.reserve(100);
    vecInt.resize(100);
    memcpy(&vecInt[0], arrayInt, 100 * sizeof(int));
}

需要注意的是,在执行memcpy前一定要保证vector中存在至少100个元素,否则执行memcpy就会异常.
更好的推荐代码是通过区间构造函数实现拷贝.

int arrayInt[100] = { 0, };
int main()
{
    for (int i = 0; i < 100; i++)
        arrayInt[i] = i;
    vector<int> vecInt(arrayInt, arrayInt+100);
}

如何把一个char 数组转化成string

最好的方法还是利用string的区间构造函数实现

char arrayChar[26];
int main()
{
    for (int i = 0; i < 26; i++)
        arrayChar[i] = 'a'+i;
    vector<int> vecInt(arrayInt, arrayInt+100);
    std::string s(arrayChar, arrayChar + 26);
}

充分利用各个容器的区间构造函数,来实现容器数据向array的转换

假如有个旧的API只能处理数组, 但是数据被你维护在某个容器中,那么笨方法是, for_each每个元素,把每个元素放到新建的数组上,然后把数组传给这个API.
更好的方法是,通过区间构造函数,任何容器上的数据,都能转换成vector数据,而vector数据因为连续内存的设计,很容易兼容需要数组的接口.

相关文章

  • EFFECTIVE+STL中文版:50条有效使用STL的经验

    《Effective STL中文版:50条有效使用STL的经验》是EffectiveC++的第3卷,被评为“值得所...

  • 常用的 STL 查找算法

    常用的 STL 查找算法 《effective STL》中有句忠告,尽量用算法替代手写循环;查找少不了循环遍历,在...

  • Effective STL 第7条

    容器中的对象如果是指针,指针指向的资源,容器没有办法自动释放. 问题引出 容器在自己析构的时候,会把包含的对象逐个...

  • Effective STL 第28条

    正确使用reverse_iterator对于任何一个容器, 使用iterator, 你只可能正向正序访问容器内部的...

  • Effective STL 第22条

    主要不要修改set mutipleSet的key

  • Effective STL 第30条

    如果是区间操作,注意确保容器具有足够的区间 这个很矛盾, 我们害怕使用数组,就是因为数组有可能越界.为了不去考虑数...

  • Effective STL 第31条

    准确的选择排序算法 如果要对一个数列进行完全的排序,那么用sort是个不错的选择.但是如果只是部分排序, 要考虑更...

  • Effective STL 第34条

    为什么有些算法需要排序的区间 binary_search算法是二分查找, 这种查找需要查找空间的序列是有序的. 为...

  • Effective STL 第19条

    理解相等于等价相等的基础是 == , 如果x==y成立,就说明x和y的值相等对于有顺序关系的容器, 为了顺序的存在...

  • Effective STL 第25条

    散列表: 用key可以作为索引快速找到对应的value. 且这些对象在容器里面不排序. 散列表和标准关联容器set...

网友评论

      本文标题:Effective STL 第16条

      本文链接:https://www.haomeiwen.com/subject/tvbdortx.html