STL_学习之_Vector用法!

本文介绍了STL中Vector的应用,包括定义、初始化及元素遍历等操作。通过具体实例展示了如何使用Vector进行数据管理。

 由于这段时间的工作接触到STL,所以就学习了一下,感觉STL很好,对于一些数据的管理很方便!

Vector是STL中的向量,实际上,按我的理解就是一个对象数组的模板,

使用之前是包含相应的头文件

#include<vector>

 

1.先是定义一个向量对象:

typedef struct myData{

      int a;

      DWORD dwPtr;

  .....

}DATA;

vector<DATA*>  vecData;

 

 

2.对向量初始化:

      DATA* pdata = new DATA;

       vecData.push_back(pdata);

   

3.元素的遍历:(指针类型元素)

  像这样!

    for(vecData::iterator itData = vecData.begin() ; itData != vecData.end() ; ++itData)

      {

            if((*itData)->a == 1)
              {
                    ......
              }

       }
 
第二种遍历:
    for(int i = 0 ; i< vecData.size() ; i++)
       {
          vecData.at(i);<=> vecData[i];
       }

 

 
学习笔记而已,见笑了!!!

<think>我们分析的是`std::vector`的`front()`成员函数的一个实现片段(来自MSVC标准库)。这段代码的功能是返回vector中第一个元素的引用,同时包含一些调试和安全检查。 ### 代码解析 ```cpp _NODISCARD _CONSTEXPR20 _Ty& front() noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; #if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_My_data._Myfirst != _My_data._Mylast, "front() called on empty vector"); #endif return *_My_data._Myfirst; } ``` #### 1. 宏和属性说明 - `_NODISCARD`: 这是一个属性,提示调用者不能忽略返回值(即必须使用返回值),否则编译器可能会给出警告。 - `_CONSTEXPR20`: 表示该函数是C++20的`constexpr`函数,可以在编译时求值。 - `noexcept`: 表示该函数不会抛出异常。 - `/* strengthened */`: 注释,表示该函数的异常规范被加强(即由实现保证不会抛出异常,而标准可能允许抛出异常,但这里实现为`noexcept`)。 #### 2. 内部实现 - `auto& _My_data = _Mypair._Myval2;`: 获取vector内部的数据结构(通常包含指向首尾的指针等)。 - 条件编译检查:当启用了强化模式(hardening)或迭代器调试级别非0时,执行安全检查。 - `_STL_VERIFY(condition, message)`: 如果条件为假,则触发断言(可能中断程序)并输出错误信息。这里检查`_My_data._Myfirst`(指向第一个元素的指针)是否不等于`_My_data._Mylast`(指向最后一个元素之后的指针)。如果相等,说明vector为空,调用`front()`是非法的。 - 返回第一个元素:`*_My_data._Myfirst`。 #### 3. 安全强化 - 在调试模式或开启安全检查时,会验证vector非空,避免未定义行为(访问空vector的front是UB)。 - 在发布模式且未开启安全强化时,可能跳过检查,以提高性能(但调用空vector的front()仍为UB)。 ### 重要知识点 #### 1. `_NODISCARD`的作用 - 防止误用:例如,如果用户调用`front()`而不使用返回值,可能是一个错误(因为通常调用`front()`是为了获取值)。使用`_NODISCARD`可以让编译器警告这种可能无意义的调用。 #### 2. `noexcept`的重要性 - 该函数不会抛出异常,因为只是返回一个引用。但标准库实现选择标记为`noexcept`,这允许一些优化,并可以在需要不抛出的上下文中使用(例如,在`std::vector`的移动操作中)。 #### 3. 调试检查 - 标准库实现通常包含调试模式,用于在开发阶段捕获错误。`_ITERATOR_DEBUG_LEVEL`宏控制调试级别,级别越高,检查越严格。 - 安全强化(hardening)是一种在发布版本中也加入安全检查的机制,以增强程序安全性。 ### 类似实现对比 在GCC的libstdc++中,`front()`的实现如下: ```cpp reference front() _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); return *begin(); } ``` 其中`__glibcxx_requires_nonempty()`在调试模式下会检查非空。 ### 安全使用建议 调用`front()`前,应确保vector非空。可以使用`empty()`成员函数检查: ```cpp std::vector<int> vec; // ... 填充vec ... if (!vec.empty()) { int& first = vec.front(); // 使用first... } ``` ### 相关问题 §§相关问题§§: 1. C++中`_NODISCARD`属性通常用于哪些场景? 2. 为什么`std::vector`的`front()`和`back()`在空容器上调用是未定义行为? 3. `noexcept`关键字在C++中有什么作用?它如何影响程序性能? 4. 在C++标准库中,迭代器调试级别(`_ITERATOR_DEBUG_LEVEL`)的主要作用是什么?</think>### `std::vector::front()` 实现深度解析 这段代码是 MSVC 标准库中 `std::vector::front()` 的实现,展示了现代 C++ 标准库的关键设计理念。以下是详细分析: #### 1. 函数签名解析 ```cpp _NODISCARD _CONSTEXPR20 _Ty& front() noexcept /* strengthened */ ``` - **`_NODISCARD`**:强制编译器检查返回值是否被使用 ```cpp [[nodiscard]] // C++17 标准属性 ``` - **`_CONSTEXPR20`**:C++20 的 `constexpr` 函数 ```cpp constexpr // 可在编译期执行 ``` - **`noexcept`**:保证不抛出异常 ```cpp /* 实现强化:标准允许抛出异常,但此实现保证不抛出 */ ``` #### 2. 安全验证机制 ```cpp #if _MSVC_STL_HARDENING_VECTOR || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_My_data._Myfirst != _My_data._Mylast, "front() called on empty vector"); #endif ``` - **调试模式检查**: - `_ITERATOR_DEBUG_LEVEL != 0`:调试模式开启额外检查 - `_MSVC_STL_HARDENING_VECTOR`:安全强化模式 - **`_STL_VERIFY` 宏行为**: ```cpp #define _STL_VERIFY(cond, msg) \ (cond) ? (void)0 : _STL_REPORT_ERROR(msg) ``` - 失败时调用 `_STL_REPORT_ERROR`(通常触发断点或异常) #### 3. 核心实现逻辑 ```cpp return *_My_data._Myfirst; ``` - **数据成员说明**: ```cpp struct _Vector_data { pointer _Myfirst; // 指向第一个元素 pointer _Mylast; // 指向最后一个元素的下一位 pointer _Myend; // 指向分配内存的末尾 }; ``` - **访问复杂度**:O(1) 直接访问 #### 4. 完整模拟实现 ```cpp template <typename T> class Vector { T* _Myfirst; T* _Mylast; T* _Myend; public: [[nodiscard]] constexpr T& front() noexcept { // 调试模式安全检查 #if defined(DEBUG) || defined(_HARDENING) if (_Myfirst == _Mylast) { std::cerr << "front() called on empty vector\n"; std::terminate(); // 或 throw std::out_of_range } #endif return *_Myfirst; } }; ``` ### 关键设计原则 1. **零开销抽象原则**: ```cpp // 发布模式编译后等价于: T& front() { return *_Myfirst; } ``` 2. **安全与性能平衡**: | 编译模式 | 安全检查 | 性能影响 | |-------------------|----------|----------| | 发布模式 (`NDEBUG`)| 无 | 最优 | | 调试模式 | 有 | 稍慢 | | 安全强化模式 | 有 | 稍慢 | 3. **异常安全保证**: - 标准要求:可能抛出 `nothing`(但未强制要求) - 此实现:明确标记 `noexcept` ### 使用注意事项 **正确用法**: ```cpp std::vector<int> v{1, 2, 3}; if (!v.empty()) { int& first = v.front(); // 安全访问 } ``` **危险用法**: ```cpp std::vector<int> v; int& x = v.front(); // 未定义行为! // 调试模式:触发断言/终止 // 发布模式:内存访问冲突 ``` ### 与 `back()` 的对比 ```cpp [[nodiscard]] _CONSTEXPR20 _Ty& back() noexcept { auto& _My_data = _Mypair._Myval2; _STL_VERIFY(_My_data._Myfirst != _My_data._Mylast, "back() called on empty vector"); return *(_My_data._Mylast - 1); // 唯一区别 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值