C++中指针使用详解(4)指针的高级应用汇总
C++ 中指针的高级应用非常丰富,掌握这些内容能让你写出更高性能、更底层控制力强的代码。下面是应用模块梳理和例子讲解。
目录预览
- 函数指针与回调机制
- 指针数组 vs 数组指针
- 指针与类成员函数(成员函数指针)
- 智能指针(
unique_ptr
,shared_ptr
,weak_ptr
) - 指针与继承、虚函数表(vtable)
- 指针与内存对齐、指针算术
- 指针类型转换(
reinterpret_cast
,static_cast
) - 指针模拟多态和接口
- 自定义 allocator / 内存池(高级性能优化)
- 指针与并发(原子指针、锁自由结构)
1. 函数指针与回调机制
声明与使用
void hello() {std::cout << "Hello\n";
}void call(void (*func)()) {func(); // 调用传入的函数指针
}
也可以传入带参数的函数:
void print(int x) {std::cout << x << "\n";
}void call(void (*func)(int), int val) {func(val);
}
2. 指针数组 vs 数组指针
表达式 | 含义 |
---|---|
int* arr[10] | 数组,每个元素是 int* |
int (*arr)[10] | 指向数组 的指针 |
示例
int* pArr[10]; // 10 个 int 指针
int arr[10];
int (*p)[10] = &arr; // 一个指针,指向包含 10 个 int 的数组
3. 成员函数指针
声明和调用成员函数指针:
class A {
public:void show() { std::cout << "A::show\n"; }
};void (A::*pFunc)() = &A::show;A a;
(a.*pFunc)(); // 使用成员函数指针调用
注意:成员函数指针与普通函数指针不同,它需要对象实例才能调用。
4. 智能指针(现代 C++ 的推荐方式)
std::unique_ptr
std::unique_ptr<int> p = std::make_unique<int>(10);
- 不能拷贝,只能转移
- 自动析构,无需手动 delete
std::shared_ptr
std::shared_ptr<int> p1 = std::make_shared<int>(20);
std::shared_ptr<int> p2 = p1; // 引用计数 +1
- 多个指针共享对象生命周期
std::weak_ptr
避免循环引用
std::weak_ptr<int> wp = p1;
5. 指针与虚函数表(vtable)
基类指针指向派生类(多态)
class Base {
public:virtual void foo() { std::cout << "Base\n"; }
};class Derived : public Base {
public:void foo() override { std::cout << "Derived\n"; }
};Base* b = new Derived();
b->foo(); // 输出 "Derived"
底层通过虚函数表(vtable)实现,vptr 指针指向类的虚函数表。
6. 内存对齐与指针算术
struct alignas(16) Vec4 {float x, y, z, w;
};
指针算术是按类型大小偏移的:
int* p = arr;
p += 2; // 实际偏移 sizeof(int) * 2 字节
7. 指针类型转换
int a = 10;
void* vp = &a;int* ip = static_cast<int*>(vp); // OK
float* fp = reinterpret_cast<float*>(ip); // 危险,类型错配
类型转换建议顺序:
static_cast
:安全的编译期转换reinterpret_cast
:位级别转换,需小心const_cast
:去掉const
限定dynamic_cast
:用于 RTTI 下的多态类型转换(带virtual
)
8. 指针模拟多态与接口
struct Interface {void (*run)(void*);void* self;
};void do_something(void* p) {std::cout << "Run on raw object\n";
}Interface iface = { do_something, nullptr };
iface.run(iface.self);
- 类似于 C 风格接口表
- 可用于插件系统、自定义脚本语言嵌入等
9. 自定义内存分配器(性能优化)
使用自定义 pointer allocator,跳过 malloc/new:
template <typename T>
class MyAllocator {...T* allocate(size_t n) { return static_cast<T*>(::operator new(n * sizeof(T))); }
};
结合 STL 使用:
std::vector<int, MyAllocator<int>> v;
也可做内存池管理(如用于点云、游戏对象池)
10. 指针与并发
std::atomic<T*>
保证多线程访问安全- 可用于 lock-free 数据结构
std::atomic<int*> ap;
int* p = new int(42);
ap.store(p);
高级:Hazard Pointer、ABA 问题、Compare-And-Swap(CAS)
总结脑图式表
┌────────────┐│ 高级指针用法│└────────────┘↓┌────────────┬────────────┬────────────┬────────────┐│ 函数指针 │ 成员指针 │ 智能指针 │ 指针算术 │├────────────┴────────────┴────────────┴────────────┤│ 内存池 │ 指针与类 │ vtable 多态│ 类型转换 │├────────────┬────────────┬────────────┬────────────┤│ ABI + 栈帧 │ 并发原子指针│ 插件接口 │ STL allocator │└────────────┴────────────┴────────────┴────────────┘