009 C++的原始指针(Raw Pointer)
作者Lou Xiao, deepseek创建时间2025-04-02 07:14:51更新时间2025-04-02 07:14:51
1. 原始指针基本概念
原始指针是C++中最基础的指针类型,直接存储内存地址。它们提供底层内存操作能力,但也需要开发者自行管理生命周期。
1.1 指针声明语法
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
T* ptr; // 指向类型T的指针
2
const T* ptr; // 指向const T的指针
3
T* const ptr; // const指针(不可修改地址)
2. 指针基本操作
2.1 取地址与解引用
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int value = 42;
2
int* ptr = &value; // 取地址
3
*ptr = 100; // 解引用并修改
2.2 指针算术运算
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int arr[5] = {1,2,3,4,5};
2
int* p = arr;
3
p++; // 指向arr[1]
4
p += 2; // 指向arr[3]
2.3 指针比较
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
if (ptr1 == ptr2) {...}
2
if (ptr != nullptr) {...}
3. 指针与数组
3.1 数组名退化
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int arr[3] = {1,2,3};
2
int* p = arr; // 数组名退化为指针
3.2 指针遍历数组
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
for (int* p = arr; p != arr + 3; ++p) {
2
std::cout << *p << " ";
3
}
4. 多级指针
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int value = 42;
2
int* p = &value;
3
int** pp = &p; // 二级指针
4
int*** ppp = &pp; // 三级指针
5. 指针与const
5.1 组合形式
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
const int* p1; // 指向const int的指针
2
int const* p2; // 同上,等价写法
3
int* const p3; // const指针,指向int
4
const int* const p4; // const指针,指向const int
5.2 类型转换
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
const int* p1 = &value;
2
int* p2 = const_cast<int*>(p1); // 去除const限定
6. 函数与指针
6.1 指针参数
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
void modify(int* ptr) {
2
*ptr = 100;
3
}
6.2 指针返回值
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int* create_array(size_t size) {
2
return new int[size];
3
}
6.3 函数指针
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
void (*funcPtr)(int) = &myFunction;
2
funcPtr(42);
7. 动态内存管理
7.1 new/delete
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int* p = new int(42); // 单个对象
2
delete p;
3
4
int* arr = new int[10]; // 数组
5
delete[] arr;
7.2 malloc/free
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int* p = (int*)malloc(sizeof(int));
2
free(p);
8. 指针安全问题
8.1 常见问题
- 空指针解引用
- 野指针(Dangling pointer)
- 内存泄漏
- 双重释放
- 数组越界
8.2 防御性编程
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
if (ptr != nullptr) {
2
*ptr = value;
3
}
4
5
// 使用RAII管理资源
6
class PointerWrapper {
7
T* ptr;
8
public:
9
explicit PointerWrapper(T* p) : ptr(p) {}
10
~PointerWrapper() { delete ptr; }
11
};
9. 指针与类型转换
9.1 C风格转换
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
void* vp = ...;
2
int* ip = (int*)vp;
9.2 C++风格转换
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
const int* cip = ...;
2
int* ip = const_cast<int*>(cip);
3
4
Base* b = ...;
5
Derived* d = dynamic_cast<Derived*>(b);
10. 指针最佳实践
- 优先使用智能指针:unique_ptr/shared_ptr
- 明确指针所有权:文档说明指针所有权关系
- 避免裸new/delete:使用RAII包装器
- 检查nullptr:在使用前验证指针有效性
- 限制指针作用域:尽量缩小指针可见范围
- 使用引用替代:当不需要nullptr或重指向时
11. 现代C++替代方案
11.1 智能指针
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
std::unique_ptr<int> up(new int(42));
2
std::shared_ptr<int> sp = std::make_shared<int>(42);
11.2 引用
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
void process(const std::string& str); // 优先使用const引用
11.3 容器与视图
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
std::vector<int> vec{1,2,3};
2
std::span<int> sp(vec); // C++20
12. 指针性能考量
- 内存访问开销:指针解引用比直接访问慢
- 缓存友好性:连续内存访问效率更高
- 别名分析影响:指针可能限制编译器优化
- 虚函数调用:通过指针的虚函数调用有额外开销
13. 特殊指针类型
13.1 void指针
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
void* vp = ...;
2
// 必须转换为具体类型后才能使用
13.2 函数指针
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
using Handler = void(*)(int);
2
Handler h = &myHandler;
13.3 成员指针
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
struct S { int value; };
2
int S::* ptr = &S::value;
3
S s;
4
s.*ptr = 42;
14. 指针与多态
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
class Base { virtual void foo(); };
2
class Derived : public Base {};
3
4
Base* b = new Derived();
5
b->foo(); // 多态调用
6
delete b;
15. 指针调试技巧
- 使用调试器:检查指针值和指向内容
- 标记特殊值:如0xDEADBEEF标记已释放内存
- 边界检查工具:AddressSanitizer等
- 日志记录:重要指针操作添加日志
16. 总结
原始指针是C++强大但危险的特征:
- 提供底层内存控制能力
- 需要开发者自行管理生命周期
- 容易引入各种内存错误
- 在现代C++中应谨慎使用
最佳实践:
- 新代码优先使用智能指针和引用
- 必须使用时严格遵循资源管理规范
- 添加充分注释说明指针所有权
- 使用静态分析工具检查指针使用
文章目录