标准库智能指针如std::unique_ptr<T[]>和std::shared_ptr<T[]>支持下标访问,通过重载operator[]可为自定义智能指针实现类似原生数组的访问方式,提升代码可读性与安全性。

当我们在C++中处理智能指针管理的动态数组时,如何像操作原生数组一样自然地使用下标运算符
[]
std::unique_ptr<T[]>
std::shared_ptr<T[]>
ptr[index]
operator[]
要实现智能指针数组的下标访问,核心在于理解标准库智能指针的特性以及如何为自定义类型重载
operator[]
对于标准库提供的智能指针:
std::unique_ptr<T[]>
std::shared_ptr<T[]>
new T[size]
[]
myArrayPtr[index]
delete[]
#include <iostream>
#include <memory> // For std::unique_ptr and std::shared_ptr
class MyObject {
public:
int id;
MyObject(int i = 0) : id(i) {}
void print() const { std::cout << "MyObject ID: " << id << std::endl; }
};
int main() {
// 使用 std::unique_ptr<T[]>
std::unique_ptr<MyObject[]> uniqueArray(new MyObject[5]);
for (size_t i = 0; i < 5; ++i) {
uniqueArray[i].id = i * 10; // 直接使用下标访问和修改
}
for (size_t i = 0; i < 5; ++i) {
uniqueArray[i].print();
}
// uniqueArray 在作用域结束时会自动调用 delete[]
std::cout << "--------------------" << std::endl;
// 使用 std::shared_ptr<T[]>
std::shared_ptr<MyObject[]> sharedArray(new MyObject[3]);
for (size_t i = 0; i < 3; ++i) {
sharedArray[i].id = i + 100;
}
for (size_t i = 0; i < 3; ++i) {
sharedArray[i].print();
}
// sharedArray 在最后一个引用计数归零时会自动调用 delete[]
return 0;
}对于自定义智能指针或封装了数组的类: 如果你正在实现一个自己的智能指针类,或者一个容器类,而这个类内部管理着一个动态数组,并且你希望它也能通过
[]
operator[]
const
const
#include <cstddef> // For size_t
#include <stdexcept> // For std::out_of_range
#include <cassert> // For assert (debug builds)
template <typename T>
class MyArraySmartPtr {
private:
T* data;
size_t size;
public:
explicit MyArraySmartPtr(size_t s) : size(s) {
data = new T[size];
// 简单初始化
for (size_t i = 0; i < size; ++i) {
data[i] = T(); // 默认构造
}
}
// 禁用拷贝构造和赋值,或者实现深拷贝,这里为简化禁用
MyArraySmartPtr(const MyArraySmartPtr&) = delete;
MyArraySmartPtr& operator=(const MyArraySmartPtr&) = delete;
~MyArraySmartPtr() {
delete[] data;
}
// 非const版本:允许读写访问
T&amp; operator[](size_t index) {
// 生产环境中建议抛出异常,如 std::out_of_range
// assert(index < size && "Index out of bounds!");
if (index >= size) {
throw std::out_of_range("MyArraySmartPtr: Index out of bounds");
}
return data[index];
}
// const版本:只允许只读访问
const T&amp;amp;amp; operator[](size_t index) const {
// assert(index < size && "Index out of bounds!");
if (index >= size) {
throw std::out_of_range("MyArraySmartPtr: Index out of bounds");
}
return data[index];
}
size_t getSize() const { return size; }
};
// 示例用法
// int main() {
// MyArraySmartPtr<int> myArr(10);
// for (size_t i = 0; i < myArr.getSize(); ++i) {
// myArr[i] = static_cast<int>(i * 100);
// }
//
// const MyArraySmartPtr<int>& constArr = myArr;
// for (size_t i = 0; i < constArr.getSize(); ++i) {
// std::cout << constArr[i] << " ";
// }
// std::cout << std::endl;
//
// try {
// myArr[100] = 5; // 尝试越界访问
// } catch (const std::out_of_range& e) {
// std::cerr << "Error: " << e.what() << std::endl;
// }
//
// return 0;
// }在C++中,正确管理动态数组一直是性能与安全之间的平衡点,而智能指针的引入极大地简化了这一过程,并提升了代码的健壮性。最直接且推荐的方式就是使用标准库提供的
std::unique_ptr<T[]>
std::shared_ptr<T[]>
std::unique_ptr<T[]>
new T[size]
std::unique_ptr<T[]>
delete[]
delete[]
delete
delete[]
立即学习“C++免费学习笔记(深入)”;
std::shared_ptr<T[]>
std::shared_ptr
delete[]
一个常见的误区是试图用
std::unique_ptr<T>
[]
new T[size]
std::unique_ptr<T>
delete
delete[]
T[]
T
此外,对于更复杂的动态数组需求,尤其是需要动态增删元素时,
std::vector<T>
push_back
pop_back
resize
std::vector<std::unique_ptr<T>>
std::vector
std::unique_ptr
为自定义智能指针或容器类重载下标运算符
operator[]
首先,提供const
const
const
T&
const
const T&amp;amp;
const
const
operator[]
const
// 示例:MyArraySmartPtr中的重载
T& operator[](size_t index) { /* ... */ return data[index]; }
const T&amp;amp; operator[](size_t index) const { /* ... */ return data[index]; }其次,务必进行边界检查。这是确保程序安全性的核心。原始指针的
[]
operator[]
assert(index < size)
std::out_of_range
第三,返回类型应是引用(T&
const T&amp;amp;
operator[]
T
第四,考虑效率与内联。
operator[]
data[index]
最后,明确所有权语义。虽然这更多是智能指针类整体的设计考量,但在
operator[]
operator[]
从表面上看,智能指针数组访问和原始指针数组访问在语法上几乎是相同的,都通过
ptr[index]
相似之处:
[]
mySmartPtr[i]
myRawPtr[i]
[]
*(ptr + index)
不同之处:
内存管理: 这是最核心的区别。
new[]
delete[]
delete[]
所有权语义:
std::unique_ptr<T[]>
std::shared_ptr<T[]>
安全性:
myRawPtr[100]
std::unique_ptr<T[]>
std::shared_ptr<T[]>
operator[]
std::out_of_range
运行时开销:
std::unique_ptr
std::shared_ptr
意图表达:
std::unique_ptr<T[]>
T
delete[]
总而言之,智能指针数组访问在保持原始指针的便利语法的同时,通过封装和RAII机制,彻底解决了内存管理这一C++传统痛点,提供了更安全、更健壮的动态数组管理方案。在现代C++编程中,除非有极其特殊的性能要求,否则几乎总是推荐使用智能指针或
std::vector
以上就是C++智能指针数组访问 下标运算符重载的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号