【发布时间】:2010-11-17 08:08:54
【问题描述】:
点(.)运算符和C++中的->有什么区别?
【问题讨论】:
点(.)运算符和C++中的->有什么区别?
【问题讨论】:
foo->bar() 与(*foo).bar() 相同。
由于* 和. 运算符的绑定强度,上述括号是必需的。
*foo.bar() 不起作用,因为首先评估点 (.) 运算符(请参阅operator precedence)
点 (.) 运算符不能重载,箭头 (->) 运算符可以重载。
点 (.) 运算符不能应用于指针。
【讨论】:
对于指针,我们可以使用
*pointervariable.foo
但. 运算符的优先级高于* 运算符,因此首先计算.。所以我们需要用括号强制它:
(*pointervariable).foo
但是一直键入 () 很困难,因此他们开发了-> 作为表达相同内容的快捷方式。如果您正在访问对象的属性或对象引用,请使用. 如果您正在通过指针访问对象的属性,请使用->
【讨论】:
点运算符不能重载,箭头运算符可以重载。箭头运算符通常用于指针(或行为类似指针的对象,如智能指针)。点运算符不能应用于指针。
编辑
当应用于指针箭头运算符时,相当于将点运算符应用于指针,例如ptr->field 等价于(*ptr).field。
【讨论】:
*foo)可以重载
箭头运算符类似于点,但它首先取消引用指针。 foo.bar() 在对象foo 上调用方法bar(),foo->bar 在指针foo 指向的对象上调用方法bar。
【讨论】:
foo 不是指针并且它的类型是MyType,你会得到一个编译异常:base operand of '->' has non-pointer type 'MyType'。
operator->。
. 运算符用于直接成员访问。
object.Field
箭头取消引用一个指针,以便您可以访问它指向的对象/内存
pClass->Field
【讨论】:
pSomething->someMember
等价于
(*pSomething).someMember
【讨论】:
目标。 dot 作用于物体;箭头作用于指向对象的指针。
std::string str("foo");
std::string * pstr = new std::string("foo");
str.size ();
pstr->size ();
【讨论】:
当你有指针时使用->。
当你有结构(类)时使用.。
当你想指向属于结构的属性时使用.:
structure.attribute
当您想通过指针指向具有内存引用的属性时,请使用->:
pointer->method;
或相同:
(*pointer).method
【讨论】:
请注意,-> 运算符不能用于某些事情,例如访问 operator[]。
#include <vector>
int main()
{
std::vector<int> iVec;
iVec.push_back(42);
std::vector<int>* iVecPtr = &iVec;
//int i = iVecPtr->[0]; // Does not compile
int i = (*iVecPtr)[0]; // Compiles.
}
【讨论】:
很简单,只要你看到
x->y
知道是一样的
(*x).y
【讨论】:
-> 只是指针解引用的语法糖,
正如其他人所说:
指针->方法();
是一种简单的说法:
(*指针).method();
如需更多指针乐趣,请查看 Binky 和他的解引用魔杖:
【讨论】:
两者之间最简单的区别是“->”在查看对象字段、函数等之前取消引用指针,而“.”不首先取消引用。当您有指向对象的指针时使用“->”,并使用“。”当您使用对象的实际实例时。
另一种等效的写法可能是先在指针上使用取消引用的“*”,然后再使用“.”。我们使用“->”跳过中间人。
还有其他差异,但其他答案已经广泛涵盖了这一点。
如果您有 Java 的背景,这可能会让您感到困惑,因为在 Java 中,一切都是指针。这意味着没有理由让符号不首先取消引用您的指针。然而,在 c++ 中,你必须更加小心地记住什么是指针,什么不是指针,最好用前缀“p_”或简单地“p”来标记它们。
【讨论】:
. (点)运算符通常用于从类的实例(或类的静态字段/方法)中获取字段/调用方法。
p.myField, p.myMethod() - p 类的实例
->(箭头)运算符用于从类指向的内容中获取字段/调用方法。
p->myField, p->myMethod() - p 指向一个类
【讨论】:
当我们使用指针时使用 -> 运算符,否则使用点。 所以如果我们有一个像这样的结构类:
struct class{ int num_students; int yr_grad; };
我们有一个类* curr_class(类指针)的实例,然后要访问我们要做的学生数量
cout << curr_class->num_students << endl;
如果我们有一个简单的类对象,比如 class_2016,我们会这样做
cout << class_2016.num_students << endl;
对于指向类的指针,-> 操作符等价于
(*obj).mem_var
注意:对于一个类,访问该类的成员函数的方式也会是一样的
【讨论】: