点号 . 和箭头 -> 的区别取决于左边操作数类型:对象或引用用 .,指针用 ->;-> 本质是 (*p).member 的语法糖;智能指针通过重载 operator-> 实现 -> 调用;引用不可用 ->,裸指针不可用 .。

点号 . 和箭头 -> 的区别,只取决于左边操作数的类型:是对象(或引用)就用 .,是指针就用 ->;混用会直接编译失败,没有例外。
什么时候必须用 ->?
当左边是一个指向类/结构体的指针时,-> 是唯一合法选择。它本质是 (*p).member 的语法糖,但省略括号和解引用符号,更安全也更清晰。
-
std::string *p = new std::string("hello"); p->length();✅ 合法 -
p.length();❌ 编译错误:error: request for member 'length' in 'p', which is of pointer type - 链表遍历中:
node = node->next;—— 这里node是Node*,next是成员变量,必须用->
什么时候只能用 .?
当左边是对象本身、或对象的引用(T& 或 const T&)时,必须用 .。引用不是指针,不涉及地址解引用,所以不能用 ->。
-
std::vector<int> v = {1,2,3}; v.size();</int>✅ -
const auto& ref = v; ref.empty();✅ 引用仍用. -
ref->size();❌ 错误:引用类型不支持->,除非该类型重载了operator->(如智能指针)
为什么 std::unique_ptr<t></t> 能用 ->?
这不是特例,而是重载行为。智能指针(unique_ptr、shared_ptr)显式定义了 operator->(),返回所管理对象的指针,从而让 p->func() 可以“穿透”一层间接性。
-
std::unique_ptr<:string> p = std::make_unique<:string>("ok"); p->c_str();</:string></:string>✅ - 这等价于
(*p).c_str(),而*p触发了operator*,再调用. - 普通裸指针没这种能力,也不能给它加重载 —— 所以裸指针 +
.永远非法
容易踩的坑:引用 vs 指针,还有 const 限定
最常出错的是把引用当成指针,或者忽略 const 对成员访问权限的影响。
-
const std::string *p; p->c_str();✅ 指针可读,c_str()是 const 成员函数 -
const std::string &s; s.length();✅length()是 const 成员,允许通过 const 引用调用 -
s.append("x");❌ 错误:非 const 成员函数不能通过 const 引用调用 - 写
s->length()?直接报错 —— 引用类型没有内置->,也没重载,别试
真正卡住人的往往不是规则本身,而是没看清变量声明时的 * 或 &;多看一眼类型,比查文档更快解决问题。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











