陕西省信用建设官方网站,公司网站设计好,定制网站开发哪个好,荆州哪里做网站实现一个安全向量模板类 SiVector#xff0c;其设计目标是#xff1a;在保持 std::vector 易用性的基础上#xff0c;增强越界访问的安全性#xff08;避免崩溃#xff09;#xff0c;同时兼容 std::vector 的核心接口和使用习惯。支持嵌套使用#xff08;如 SiVector其设计目标是在保持 std::vector 易用性的基础上增强越界访问的安全性避免崩溃同时兼容 std::vector 的核心接口和使用习惯。支持嵌套使用如 SiVectorstd::vectordouble提供越界访问时的默认值返回或自动扩容机制并支持与 std::vector 的双向类型转换。
实现
代码示例
#include string
#include iostream
#include vector
#include iteratortemplate typename T
class SiVector {
public:SiVector(T value) : m_defaultValue(value) {}SiVector(std::vectorT data) : m_datas(data) {}SiVector(std::vectorT data, T value) : m_datas(data), m_defaultValue(value) {}// 构造函数模仿std::vector SiVector() : m_defaultValue(T()) {} // 构造指定大小的容器元素初始化为value默认用默认值explicit SiVector(uint32_t size, const T value T()) : m_datas(size, value), m_defaultValue(T()) {}// 从迭代器范围构造template typename InputItSiVector(InputIt first, InputIt last): m_datas(first, last), m_defaultValue(T()) {}// 从初始化列表构造支持 SiVectorint v {1,2,3};SiVector(std::initializer_listT init) : m_datas(init), m_defaultValue(T()) {}// 拷贝构造SiVector(const SiVector other) default;// 移动构造SiVector(SiVector other) noexcept default;// 类型别名模仿std::vector的迭代器类型// using value_type T;using iterator typename std::vectorT::iterator;using const_iterator typename std::vectorT::const_iterator;// using reference T;// using const_reference const T;// using size_type size_t;// 赋值操作模仿std::vector SiVector operator(const SiVector other) default;SiVector operator(SiVector other) noexcept default;SiVector operator(std::initializer_listT init) {m_datas init;return *this;}// 重载[]越界时返回默认值const版T operator[](uint32_t index) {if (index m_datas.size()) {std::cout index out of range. ;m_datas.resize(index 1, m_defaultValue);}return m_datas[index];}const T operator[](uint32_t index) const {if (index m_datas.size()) {std::cout index out of range. ;return m_defaultValue;}return m_datas[index];}T at(uint32_t index) {if (index m_datas.size()) {std::cout at index out of range. ;return m_defaultValue;}return m_datas[index];}const T at(uint32_t index) const {if (index m_datas.size()) {std::cout at index out of range. ;return m_defaultValue;}return m_datas[index];}// 首尾元素访问T front() { return m_datas.front(); }const T front() const { return m_datas.front(); }T back() { return m_datas.back(); }const T back() const { return m_datas.back(); }// 迭代器支持范围for循环 iterator begin() noexcept { return m_datas.begin(); }// const_iterator const begin() noexcept { return m_datas.begin(); }const_iterator const cbegin() noexcept { return m_datas.cbegin(); }iterator end() noexcept { return m_datas.end(); }// const_iterator const end() noexcept { return m_datas.end(); }const_iterator const cend() noexcept { return m_datas.cend(); }// 容量操作与std::vector一致 bool empty() const noexcept { return m_datas.empty(); }uint32_t const size() noexcept { return m_datas.size(); }uint32_t capacity() const noexcept { return m_datas.capacity(); }// 调整大小多余元素用默认值填充void resize(uint32_t size) { m_datas.resize(size, m_defaultValue); } void resize(uint32_t size , const T value) { m_datas.resize(size, value); }// 预留容量void reserve(uint32_t size) { m_datas.reserve(size); }void shrink_to_fit() { m_datas.shrink_to_fit(); }operator std::vectorT() const {return m_datas;}// 修改操作与std::vector一致 void push_back(const T value) { m_datas.push_back(value); }void push_back(T value) { m_datas.push_back(std::move(value)); }template typename... ArgsT emplace_back(Args... args) { return m_datas.emplace_back(std::forwardArgs(args)...); } // std::forwardArgs(args)... 中的 ... 是必须的它的作用是将参数包 args 中的所有参数逐个展开传递给 m_datas.emplace_back. 保持每个参数的转发语义完美转发void pop_back() {if (!m_datas.empty()) {m_datas.pop_back();}}// 插入元素在pos位置插入valueiterator insert(const iterator pos, const T value) {return m_datas.insert(pos, value);}iterator insert(const iterator pos, uint32_t size, const T value) {return m_datas.insert(pos, size, value);}// 清除元素void clear() noexcept {m_datas.clear();}// 交换两个容器void swap(SiVector other) noexcept {m_datas.swap(other.m_datas);std::swap(m_defaultValue, other.m_defaultValue);}operator std::vectorstd::vectorT() const {std::vectorstd::vectorT result;for (uint32_t i 0; i m_datas.size(); i) {result.push_back(m_datas[i]); }return result;}void setDefault(const T defaultValue) {m_defaultValue defaultValue;}private:std::vectorT m_datas;T m_defaultValue{0};
};int main() {std::vectorstd::vectordouble data{{0.2, 0.5}, {0.4, 100.5, 100.6}};SiVectorstd::vectordouble vec(data);uint32_t index 0;for (auto it : vec) {std::cout index[ index ] std::endl;index;for (const auto in : it) {std::cout value : in std::endl; }}std::vectorstd::vectordouble vec1 vec;index 0;for (auto it : vec1) {std::cout index[ index ] std::endl;index;for (const auto in : it) {std::cout value : in std::endl; }} std::cout vec[10000][5000] std::endl;std::vectordouble vec2 vec[3];// 访问vec2[5]有可能崩溃std::cout vec2[5] vec2.size() std::endl;return 1;
}重点解释
1. 类定义与模板基础
template typename T
class SiVector { ... };template typename T模板类定义使 SiVector 支持任意数据类型如 int、double、std::vectordouble 等具备通用性。核心成员
m_datas内部使用 std::vectorT 存储数据复用标准容器的内存管理逻辑m_defaultValue越界访问时返回的默认值通过 setDefault 可自定义。2. 构造函数兼容 std::vector 的初始化方式
SiVector 提供了多种构造函数覆盖 std::vector 的常见初始化场景
// 无参构造
SiVector() : m_defaultValue(T()) {} // 指定大小和初始值构造explicit避免隐式类型转换
explicit SiVector(uint32_t size, const T value T()) : m_datas(size, value), m_defaultValue(T()) {}// 迭代器范围构造支持从其他容器复制元素
template typename InputIt
SiVector(InputIt first, InputIt last): m_datas(first, last), m_defaultValue(T()) {}// 初始化列表构造支持 SiVectorint v {1,2,3}; 语法
SiVector(std::initializer_listT init) : m_datas(init), m_defaultValue(T()) {}// 拷贝构造与移动构造default 复用编译器默认实现
SiVector(const SiVector other) default;
SiVector(SiVector other) noexcept default;explicit修饰单参数构造函数避免意外的隐式类型转换如 SiVectorint v 5; 会编译报错需显式构造。 default对拷贝/移动构造使用默认实现编译器会自动生成“逐成员拷贝/移动”的逻辑简洁高效。
3. 元素访问安全的 operator[] 与 at()
SiVector 的核心安全特性体现在元素访问接口解决了 std::vector 越界访问崩溃的问题
1operator[] 重载
// 非const版本越界时自动扩容保证修改操作安全
T operator[](uint32_t index) {if (index m_datas.size()) {std::cout index out of range. ;m_datas.resize(index 1, m_defaultValue); // 扩容并填充默认值}return m_datas[index];
}
// const版本越界时返回默认值只读场景不修改容器
const T operator[](uint32_t index) const {if (index m_datas.size()) {std::cout index out of range. ;return m_defaultValue; // 不扩容返回默认值}return m_datas[index];
}核心逻辑通过 index m_datas.size() 检查越界非const对象越界时自动扩容确保后续访问有效const对象越界时返回默认值避免修改const对象。优势既避免了 std::vector::operator[] 越界导致的未定义行为崩溃/数据错乱又保持了类似数组的便捷访问语法。
2at() 方法
T at(uint32_t index) {if (index m_datas.size()) {std::cout at index out of range. ;return m_defaultValue; // 越界返回默认值与std::vector::at()抛异常不同}return m_datas[index];
}与 std::vector::at() 不同std::vector::at() 越界会抛出 std::out_of_range 异常而 SiVector::at() 越界返回默认值进一步避免程序终止。
4. 迭代器支持范围for循环
// 类型别名复用std::vector的迭代器类型
using iterator typename std::vectorT::iterator;
using const_iterator typename std::vectorT::const_iterator;// 迭代器接口
iterator begin() noexcept { return m_datas.begin(); }
const_iterator cbegin() noexcept { return m_datas.cbegin(); }
iterator end() noexcept { return m_datas.end(); }
const_iterator cend() noexcept { return m_datas.cend(); }作用通过提供 begin()/end() 等迭代器接口SiVector 支持 C 范围for循环for (auto x : vec) { ... }语法与 std::vector 完全一致。实现逻辑直接复用内部 m_datasstd::vector的迭代器无需手动实现迭代器逻辑简化代码且保证兼容性。
5. 容量管理与 std::vector 行为一致
// 容量操作
uint32_t const size() noexcept { return m_datas.size(); } // 实际元素数量
uint32_t capacity() const noexcept { return m_datas.capacity(); } // 已分配内存容量
void resize(uint32_t size) { m_datas.resize(size, m_defaultValue); } // 调整大小填充默认值
void reserve(uint32_t size) { m_datas.reserve(size); } // 预分配容量不改变大小
void shrink_to_fit() { m_datas.shrink_to_fit(); } // 收缩容量至实际大小这些接口与 std::vector 功能完全一致确保用户可以像管理 std::vector 一样管理 SiVector 的内存如预分配容量提升性能、收缩容量节省内存。
6. 类型转换与 std::vector 双向兼容
SiVector 定义了类型转换运算符支持与 std::vector 无缝转换
// 转换为单层std::vectorT
operator std::vectorT() const {return m_datas;
}// 转换为嵌套std::vectorstd::vectorT针对嵌套SiVector
operator std::vectorstd::vectorT() const {std::vectorstd::vectorT result;for (uint32_t i 0; i m_datas.size(); i) {result.push_back(m_datas[i]); }return result;
}使用场景当需要调用接受 std::vector 参数的函数时SiVector 对象可自动转换为 std::vector无需手动拷贝如 std::vectorstd::vectordouble vec1 vec;。
7. 修改操作高效元素添加/删除
// 尾部添加元素支持拷贝和移动语义
void push_back(const T value) { m_datas.push_back(value); }
void push_back(T value) { m_datas.push_back(std::move(value)); }// 原地构造元素避免拷贝高效
template typename... Args
T emplace_back(Args... args) { return m_datas.emplace_back(std::forwardArgs(args)...);
}emplace_back 与完美转发
Args... args 是可变参数模板参数包支持任意数量和类型的参数std::forwardArgs(args)... 中的 ... 用于展开参数包将参数“完美转发”给 m_datas.emplace_back实现元素在容器内部直接构造无需临时对象拷贝性能优于 push_back。8. main 函数示例解析
int main() {// 1. 初始化嵌套SiVector从std::vectorstd::vectordouble构造std::vectorstd::vectordouble data{{0.2, 0.5}, {0.4, 100.5, 100.6}};SiVectorstd::vectordouble vec(data);// 2. 范围for循环遍历依赖迭代器实现for (auto it : vec) { ... }// 3. 转换为std::vector并遍历std::vectorstd::vectordouble vec1 vec;// 4. 越界访问测试非const版本自动扩容std::cout vec[10000][5000] std::endl; // 外层越界自动扩容内层同理// 5. 验证转换后的std::vector越界行为可能崩溃体现SiVector的安全性std::vectordouble vec2 vec[3];std::cout vec2[5] vec2.size() std::endl; // std::vector越界是未定义行为
}示例展示了 SiVector 的核心特性嵌套使用、范围遍历、类型转换、安全越界访问同时对比了 std::vector 越界的风险突出 SiVector 的安全性。
总结
SiVector 通过以下设计实现了“安全”与“兼容”的平衡
安全访问operator[] 和 at() 越界时返回默认值或自动扩容避免崩溃接口兼容模仿 std::vector 的构造函数、迭代器、容量管理接口降低使用成本高效转换支持与 std::vector 双向转换兼容标准库生态性能优化通过 emplace_back 完美转发和复用 std::vector 内存管理保证效率。
适用于需要频繁访问元素且对稳定性要求高的场景。