用 ->:左边是指针;用 .:左边是结构体变量。ptr->x 正确,ptr.x 报错;-> 是 (*ptr).x 的语法糖,但后者易出错;const 指针和智能指针同理,需注意空指针和内存初始化。

用 -> 还是 .?看左边是不是指针
核心就一条:如果左边是个结构体变量,用 .;如果左边是个指向结构体的指针,必须用 ->。写成 p.x(p 是指针)会编译报错:error: request for member 'x' in 'p', which is of pointer type。
常见错误是刚学完数组和指针,下意识对指针也用点号。比如:
struct Point { int x, y; };
Point p = {1, 2};
Point* ptr = &p;
// ✅ 正确
ptr->x = 10;
// ❌ 错误:编译不过
ptr.x = 10;
本质是语法糖:a->b 等价于 (*a).b,但后者括号不能省——*a.b 会被解析为 *(a.b),直接挂掉。
(*ptr).member 能用,但别这么写
理论上,解引用再点成员完全合法,但有三个现实问题:
立即学习“C++免费学习笔记(深入)”;
- 多层嵌套时括号爆炸,比如
(*(*(*pptr)).inner).field - 优先级容易踩坑:
*ptr.member实际是*(ptr.member),不是你想要的 - 可读性差,所有 C++ 代码库、标准库、开源项目都用
->,强行换写法反而增加协作成本
除非调试时临时加断点想看 (*ptr) 整体值,否则没理由不用 ->。
const 指针和 const 成员访问要对齐
指针本身 const、指向内容 const、成员变量 const,三者混搭时访问权限必须匹配:
-
const Point* p:可以改p指向,但不能通过p->x = 5改成员(除非成员是 mutable) -
Point* const p:不能改p指向,但能改成员 -
const Point* const p:两者都不能改
典型错误是传入 const Point* 参数后,在函数里写 p->x = 0,编译器立刻报 assignment of member 'x' in read-only object。
智能指针怎么访问?一样用 ->
std::unique_ptr 和 std::shared_ptr 重载了 operator->,行为和原生指针一致:
auto p = std::make_unique<Point>(); p->x = 100; // ✅ 完全没问题 // 不需要写 p.get()->x,那是画蛇添足
唯一要注意的是空指针安全:如果 p 是空的(比如 nullptr 或 move 出去了),p->x 会崩溃,和原生指针一样——智能指针不自动做空检查,该判空还得判。
最常被忽略的是:结构体里有指针成员,而你只初始化了外层结构体,忘了给内部指针 new 或赋值,这时候 ptr->inner_ptr->data 看似语法正确,实则运行时崩在第二层解引用。










