c++中用->访问指针所指对象的成员,用.访问对象实例成员;->等价于(p).m但更安全;静态成员用::访问;成员函数指针需用.或->*调用。

用 -> 运算符访问成员,不是 .
对象指针本身不包含成员,它只存地址;必须通过解引用才能访问目标对象的成员。C++ 规定:对指针用 ->,对对象实例用 .。写成 p.x 会编译失败——编译器直接报错 error: request for member 'x' in 'p', which is of pointer type。
常见错误场景:
- 刚从 Java/C# 转来,习惯性用
.访问指针成员 - 把局部对象取地址后赋给指针,后续仍用
.操作 - 函数参数是
T*,内部误用.而非->
-> 和 (*p).m 等价,但别这么写
-> 就是 (*p).m 的语法糖,两者行为完全一致。但后者多层括号易出错,尤其当 p 是复杂表达式时(比如 vec.data()->size() 写成 (*vec.data()).size() 就容易漏括号)。
实操建议:
- 一律用
->,除非重载了operator->且需要显式调用(*p).m - 如果真要写
(*p).m,确保p非空,否则解引用空指针导致未定义行为 - 智能指针如
std::unique_ptr<t></t>同样支持->,原理是重载了该运算符
访问静态成员不用 ->,用作用域解析符
静态成员属于类,不属于某个对象实例,因此指针访问静态成员和普通对象一样,都用 ::。写 p::static_member 是错的,p->static_member 也能通过编译(但语义误导),正确写法只有 T::static_member 或 p->T::static_member(极少用)。
典型陷阱:
- 误以为
ptr->static_func()是“通过对象调用”,其实它等价于T::static_func(),不依赖ptr是否为空 - 在模板中写
p->value_type,结果发现value_type是类型别名而非成员变量——这时应写T::value_type
成员函数指针访问是另一套规则,别和 -> 混
如果你拿到的是成员函数指针(比如 void (T::*func)() = &T::foo),就不能用 p->func()。必须配合对象(或指针)用 .* 或 ->* 调用:
T obj; T* p = &obj; (p->*func)(); // 正确:指针调用成员函数指针 (obj.*func)(); // 正确:对象调用
漏掉 * 或用错运算符(比如写成 p.*func)都会编译失败。这种语法极少出现在日常代码里,多见于泛型库或反射模拟逻辑中。
真正容易被忽略的是:成员函数指针的类型严格绑定类名和签名,&A::f 和 &B::f 即使函数签名相同也绝不兼容——哪怕 B 继承自 A。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











