Possible Duplicate:
When do I use a dot, arrow, or double colon to refer to members of a class in C++?
I have created the class called Kwadrat and I have three int fields inside. The Code Blocks gives me advice that i can get into the field of the object by ::
, .
and ->
. The arrow is the one that only works, but why? What's the difference between those three?
#include <iostream>
using namespace std;
class Kwadrat{
public:
int val1, val2, val3;
Kwadrat(int val1, int val2, int val3)
{
this->val1 = val1;
//this.val2 = val2;
//this::val3 = val3;
}
};
int main()
{
Kwadrat* kwadrat = new Kwadrat(1,2,3);
cout<<kwadrat->val1<<endl;
cout<<kwadrat->val2<<endl;
cout<<kwadrat->val3<<endl;
return 0;
}
Put very simple ::
is the scoping operator, .
is the access operator (I forget what the actual name is?), and ->
is the dereference arrow.
::
- Scopes a function. That is, it lets the compiler know what class the function lives in and, thus, how to call it. If you are using this operator to call a function, the function is a static
function.
.
- This allows access to a member function on an already created object. For instance, Foo x; x.bar()
calls the method bar()
on instantiated object x
which has type Foo
. You can also use this to access public class variables.
->
- Essentially the same thing as .
except this works on pointer types. In essence it dereferences the pointer, than calls .
. Using this is equivalent to (*ptr).method()
Others have answered the different syntaxes, but please note, when you are doing your couts
, you are only using ->
:
int main()
{
Kwadrat* kwadrat = new Kwadrat(1,2,3);
cout<<kwadrat->val1<<endl;
cout<<kwadrat->val2<<endl;
cout<<kwadrat->val3<<endl;
return 0;
}
The three operators have related but different meanings, despite the misleading note from the IDE.
The ::
operator is known as the scope resolution operator, and it is used to get from a namespace or class to one of its members.
The .
and ->
operators are for accessing an object instance's members, and only comes into play after creating an object instance. You use .
if you have an actual object (or a reference to the object, declared with &
in the declared type), and you use ->
if you have a pointer to an object (declared with *
in the declared type).
The this
object is always a pointer to the current instance, hence why the ->
operator is the only one that works.
Examples:
// In a header file
namespace Namespace {
class Class {
private:
int x;
public:
Class() : x(4) {}
void incrementX();
};
}
// In an implementation file
namespace Namespace {
void Class::incrementX() { // Using scope resolution to get to the class member when we aren't using an instance
++(this->x); // this is a pointer, so using ->. Equivalent to ++((*this).x)
}
}
// In a separate file lies your main method
int main() {
Namespace::Class myInstance; // instantiates an instance. Note the scope resolution
Namespace::Class *myPointer = new Namespace::Class;
myInstance.incrementX(); // Calling a function on an object instance.
myPointer->incrementX(); // Calling a function on an object pointer.
(*myPointer).incrementX(); // Calling a function on an object pointer by dereferencing first
return 0;
}
The '::' is for static members.
In C++ you can access fields or methods, using different operators, depending on it's type:
Note that :: should be used with a class name rather than a class instance, since static fields or methods are common to all instances of a class.
class AClass{
public:
static int static_field;
int instance_field;
static void static_method();
void method();
};
then you access this way:
AClass instance;
AClass *pointer = new AClass();
instance.instance_field; //access instance_field through a reference to AClass
instance.method();
pointer->instance_field; //access instance_field through a pointer to AClass
pointer->method();
AClass::static_field;
AClass::static_method();
-> is for pointers to a class instance
. is for class instances
:: is for classnames - for example when using a static member
You have a pointer to an object. Therefore, you need to access a field of an object that's pointed to by the pointer. To dereference the pointer you use *
, and to access a field, you use .
, so you can use:
cout << (*kwadrat).val1;
Note that the parentheses are necessary. This operation is common enough that long ago (when C was young) they decided to create a "shorthand" method of doing it:
cout << kwadrat->val1;
These are defined to be identical. As you can see, the ->
basically just combines a *
and a .
into a single operation. If you were dealing directly with an object or a reference to an object, you'd be able to use the .
without dereferencing a pointer first:
Kwadrat kwadrat2(2,3,4);
cout << kwadrat2.val1;
The ::
is the scope resolution operator. It is used when you only need to qualify the name, but you're not dealing with an individual object at all. This would be primarily to access a static data member:
struct something {
static int x; // this only declares `something::x`. Often found in a header
};
int something::x; // this defines `something::x`. Usually in .cpp/.cc/.C file.
In this case, since x
is static
, it's not associated with any particular instance of something
. In fact, it will exist even if no instance of that type of object has been created. In this case, we can access it with the scope resolution operator:
something::x = 10;
std::cout << something::x;
Note, however, that it's also permitted to access a static member as if it was a member of a particular object:
something s;
s.x = 1;
At least if memory serves, early in the history of C++ this wasn't allowed, but the meaning is unambiguous, so they decided to allow it.
Source: Stackoverflow.com