Coming from other C-derived languages (like Java or C#) to C++, it is at first very confusing that C++ has three ways to refer to members of a class: a::b
, a.b
, and a->b
. When do I use which one of these operators?
4 Answers
The three distinct operators C++ uses to access the members of a class or class object, namely the double colon ::
, the dot .
, and the arrow ->
, are used for three different scenarios that are always well-defined. Knowing this allows you to immediately know quite a lot about a
and b
just by looking at a::b
, a.b
, or a->b
, respectively, in any code you look at.
a::b
is only used ifb
is a member of the class (or namespace)a
. That is, in this casea
will always be the name of a class (or namespace).a.b
is only used ifb
is a member of the object (or reference to an object)a
. So fora.b
,a
will always be an actual object (or a reference to an object) of a class.a->b
is, originally, a shorthand notation for(*a).b
. However,->
is the only of the member access operators that can be overloaded, so ifa
is an object of a class that overloadsoperator->
(common such types are smart pointers and iterators), then the meaning is whatever the class designer implemented. To conclude: Witha->b
, ifa
is a pointer,b
will be a member of the object the pointera
refers to. If, however,a
is an object of a class that overloads this operator, then the overloaded operator functionoperator->()
gets invoked.
The small print:
- In C++, types declared as
class
,struct
, orunion
are considered "of class type". So the above refers to all three of them. - References are, semantically, aliases to objects, so I should have added "or reference to a pointer" to the #3 as well. However, I thought this would be more confusing than helpful, since references to pointers (
T*&
) are rarely ever used. - The dot and arrow operators can be used to refer to static class members from an object, even though they are not members of the object. (Thanks to Oli for pointing this out!)

- 13,888
- 8
- 60
- 75

- 219,715
- 46
- 258
- 445
-
13It should possibly be clarified that `.` and `->` may also be used to access class statics via an object, even though they're not strictly "members of the object". – Oliver Charlesworth Feb 13 '11 at 14:17
-
@Oli: That is indeed true. I've added it to the small print, as I think it's not common and important enough to be listed in the main text. – sbi Feb 13 '11 at 14:27
-
4For completeness, it might be worth pointing out that `operator*()` can also be overloaded, and that nothing forces that overload to be consistent with `operator->()`! (I didn't downvote BTW, just got here via a long sequence of duplicates) – juanchopanza Jul 04 '13 at 05:33
-
@OliCharlesworth would you know where that is specified in the C++ standard? – the swine Jan 15 '14 at 16:08
-
1@juanchopanza: You can't get the chaining behavior of `->` by overloading `operator*` and using `.`, however. Only `operator->` overloads get that. – Ben Voigt Sep 03 '14 at 14:59
Suggesting an alternative for sbi's point 3
a->b
is only used if a
is a pointer. It is a shorthand for (*a).b
, the b
member of the object that a
points to. C++ has two kinds of pointers, "regular" and smart pointers. For regular pointers such as A* a
, the compiler implements ->
. For smart pointers such as std::shared_ptr<A> a
, ->
is a member function of class shared_ptr
.
Rationale: the target audience of this FAQ isn't writing smart pointers. They don't need to know ->
is really called operator->()
, or that it is the only member access method that can be overloaded.
-
8No matter whether I agree with it or not, I give this a `+1` just for providing an alternative answer. – sbi Feb 14 '11 at 12:09
-
2Well, to be fair `->` is also overloaded for standard iterators which any C++ programmer should meet soon, so saying it is only used for pointers could be confusing. – Kiscsirke Mar 31 '13 at 13:57
-
@Kiscsirke "ordinary C++ programmers" don't need to be *writing* smart pointer or iterator types, just using them. "Dereferences like a pointer" applies to both. – Caleth Sep 21 '17 at 10:06
Dot operator is used in direct member selection scenarios.
print(a.b)
Here, we are accessing b
, which is a direct member of an object a
. So, primarily, a
is an object and b
is a member (function/ variable etc) of a
.
Arrow operator is used in indirect member selection scenarios.
print(a->b)
Here, we are accessing b
which is a member of the object, that is pointed to by a
. It is shorthand of (*a).b
and so here, a
is primarily a pointer to an object and b
is a member of that object.
Double Colon (Scope) operator is used in namespace related direct member selection scenarios.
print(a::b)
Here, we are accessing b
which is a member of the class/namespace a
.So, primarily, a
is a class/namespace and b
is a member (function/ variable etc) of a
.

- 743
- 6
- 17
#include <iostream>
#include <string>
using namespace std;
class Human {
private:
int age;
public:
string name;
Human(int humanAge, string humanName)
: age(humanAge), name(std::move(humanName)) {}
void DoSomething() {
cout << age << endl;
}
static void DisplayAge(const Human& person) {
cout << person.age << endl;
}
// ...
};
int main() {
// Usage of Dot(.)
Human firstMan(13, "Jim"); // firstMan is an instance of class Human
cout << firstMan.name << endl; // accessing member attributes
firstMan.DoSomething(); // accessing member functions
// Usage of Pointer Operator (->)
Human* secondMan = new Human(24, "Tom");
cout << secondMan->name << endl; // accessing member attributes
secondMan->DoSomething(); // accessing member functions
cout << (*secondMan).name << endl; // accessing member attributes
(*secondMan).DoSomething(); // accessing member functions
// Usage of Double Colon (::)
Human::DisplayAge(firstMan);
firstMan.DisplayAge(firstMan); // ok but not recommended
secondMan->DisplayAge(firstMan); // ok but not recommended
delete(secondMan);
return 0;
}
From the coding example above, we see that:
* Accessing members(attributes and functions) from an instance(or object) using the dot operator (.
)
* Accessing members(attributes and functions) from a pointer to an object(or created by new
) using the pointer operator (->
)
* Accessing static member functions from class itself without having an object as a handle using the double colon (::
). [Note: you can also invoke the static member function from a instance with .
or ->
which is not recommended]

- 1,799
- 2
- 21
- 29
-
@sbi so grumpy ha, I know it is some kind of repetition. I just want to give a explicit example to show how to use them. And where I said `->` can only be used by a pointer that allocated on the heap by `new`? Below, the second item, I think I really make it clear that `->` is for pointer. And before you downvote, you better try `className::non_static_member_function()` with c++14 by yourself. Reference is not a pointer, so it can use `.`, and I will make it more clear in my answer. – Hu Xixi Sep 05 '19 at 02:27