必须用 -> 访问指针所指向结构体的成员,如 ptr->age;ptr.age 错误,(*ptr).age 等价但冗长;-> 仅适用于结构体/类指针,智能指针和 const 限定需注意可修改性。

用 -> 运算符访问指针所指向结构体的成员
直接用 ->,不是 .,也不是先解引用再用点。这是最常见也最容易写错的地方——尤其刚从 C 切换过来或写惯了 (*ptr).member 的人。
比如有结构体:
struct Person {<br> int age;<br> char name[20];<br>};<br>Person p = {25, "Alice"};<br>Person* ptr = &p;要访问 age,必须写 ptr->age。写成 ptr.age 会编译报错:error: request for member 'age' in 'ptr', which is of pointer type 'Person*' (maybe you meant to use '->' ?)。
-
ptr->age等价于(*ptr).age,但前者更简洁、更符合语义 - 如果结构体里有嵌套结构体指针(比如
Person* boss),那就得链式用ptr->boss->age -
->只能用于指向结构体/类的指针;对普通变量或非指针类型强行用会编译失败
当结构体含 const 成员或 const 指针时,-> 行为不变但赋值受限
-> 本身不关心 const,但它暴露出来的成员是否可修改,取决于指针类型和成员声明。
例如:
const Person* ptr = &p;<br>// ptr->age = 30; // 错误:通过 const 指针不能修改成员<br>Person* const ptr2 = &p;<br>// ptr2 = nullptr; // 错误:ptr2 是 const 指针,地址不可变<br>// ptr2->age = 30; // 正确:可修改所指对象的非常量成员
立即学习“C++免费学习笔记(深入)”;
- 指针本身 const(
Person* const)→ 地址不可改,成员可改(除非成员自己是 const) - 指针指向 const(
const Person*)→ 成员不可改,哪怕成员没声明 const - 双重 const(
const Person* const)→ 地址和内容都不可改
数组中结构体指针的 -> 使用:下标和偏移都要小心
结构体数组的指针访问,本质还是指针算术 + ->,但容易混淆下标与地址偏移。
比如:
Person arr[3] = {{20,"A"},{22,"B"},{24,"C"}};<br>Person* ptr = arr; // 等价于 &arr[0]<br>ptr->age; // arr[0].age<br>(ptr+1)->age; // arr[1].age,不是 ptr[1]->age(语法错误)<br>ptr[1].age; // 合法,但这是用数组下标语法,不是 ->
-
(ptr + i)->member和ptr[i].member效果相同,但前者强调指针运算,后者更易读 - 别写
ptr[i]->member:因为ptr[i]是Person类型对象,不是指针,不能用-> - 若
ptr是二级指针(如Person** ptr),则需(*ptr)->member,多一层解引用
智能指针(std::unique_ptr/std::shared_ptr)同样支持 ->
现代 C++ 里,只要智能指针重载了 operator->()(标准库所有智能指针都重载了),就可以像原生指针一样用 ->。
#include <memory><br>auto sp = std::make_shared<Person>(28, "Bob");<br>sp->age = 29; // 完全合法,行为和 Person* 一致<br>// 不需要 sp.get()->age,除非你真要取原生指针
- 智能指针的
->是安全的:空指针调用会抛异常或触发断言(取决于实现和编译选项) -
sp.get()返回的是原生指针,仅在需要传给 C API 或做指针比较时才用,日常访问一律用sp->xxx - 自定义智能指针必须正确实现
operator->()才能支持该语法,否则编译失败
实际写的时候,-> 看似简单,但混用原生指针、智能指针、const 限定、数组偏移时,很容易漏掉一层解引用或误判可修改性。最稳妥的做法是:先确认变量类型(用 IDE hover 或 decltype 查),再决定用 -> 还是 .,以及是否允许赋值。


















