98

I created a class called Kwadrat. The class has three int fields. My Development Environment suggests that I access the fields from Kwadrat created objects via the :: & -> operators. I tried both operators, and found that the -> operator is able to successfully access the data in the objects fields, although, the same cannot be said for the -> operator. I have also found that the . operator will access class members as well. I am confused, and don't understand why there are three members for accessing object members &/or methods. Can someone please explain to me what the difference is between the three operators?


          1. ->

          2. ::

          3. .




    #include <iostream>

    using namespace std;

    class Kwadrat{

    public: 
        int val1,
            val2,
            val3;

        Kwadrat(int val1, int val2, int val3)
        {
            this->val1 = val1; // Working
            this.val2 = val2;  // Doesn't Work!
            this::val3 = val3; // Doesn't Work!
        }
    };


    int main()
    {
        Kwadrat* kwadrat = new Kwadrat(1,2,3);

        cout<<kwadrat->val1<<endl;
        cout<<kwadrat->val2<<endl;
        cout<<kwadrat->val3<<endl;

        return 0;
    }


JΛYDΞV
  • 8,532
  • 3
  • 51
  • 77
Yoda
  • 17,363
  • 67
  • 204
  • 344

8 Answers8

180

1.-> for accessing object member variables and methods via pointer to object

Foo *foo = new Foo();
foo->member_var = 10;
foo->member_func();

2.. for accessing object member variables and methods via object instance

Foo foo;
foo.member_var = 10;
foo.member_func();

3.:: for accessing static variables and methods of a class/struct or namespace. It can also be used to access variables and functions from another scope (actually class, struct, namespace are scopes in that case)

int some_val = Foo::static_var;
Foo::static_method();
int max_int = std::numeric_limits<int>::max();
Andrew
  • 24,218
  • 13
  • 61
  • 90
  • @ltjax: References are accessed like normal variables. You can do `ref = 2;` or `ref.x = 5;` for an object instance. –  Aug 10 '12 at 13:40
  • 1
    I know, I was just dropping a hint that you might want to add it to 2. – ltjax Aug 10 '12 at 13:41
  • 1
    You can have a reference to any of them. A reference always keep the same type. It's actually a different subject. –  Aug 10 '12 at 13:43
  • You can not have references to classes/namespaces. For pointers, there's no semantic difference when accessing them; but there is a difference between MyType(myRef).foo() and myRef.foo(). Hence I thought it might be a good idea to explicitly add it for 2. Your choice though. – ltjax Aug 10 '12 at 14:02
  • @ltjax: the rule for the references is the same as for objects they are refering to. For example if you make a reference to pointer you will use `->` and if to instance - `.`. So I agree with Alex and don't think that it's belongs to 2. – Andrew Aug 10 '12 at 14:06
  • 2
    The list is not comprehensive, nor 100% correct. The *scope operator* can be used in more situations to qualify an entity, even when they are not static: `void derived::f() { base::f(); }` even combined with any of the other two: `obj.base::f()`, and the *access operator* can be used to access statics: `struct test { static const int i = 1; }; test t; int j = t.i;`... – David Rodríguez - dribeas Aug 10 '12 at 14:12
  • @DavidRodríguez-dribeas: agree with scope operator. But I prefere not to access static vars/funcs via access operator – Andrew Aug 10 '12 at 14:20
  • 2
    @Andrew: Our particular preferences are unrelated to the operators. There are many things I don't like in the language, but they are still there... – David Rodríguez - dribeas Aug 10 '12 at 14:26
  • I would add a blurb that pointer->doSomething() performs an inline dereference and is really the same as (&pointer).doSomething(); and is merely syntactic sugar – Jax May 24 '16 at 23:00
30

In C++ you can access fields or methods, using different operators, depending on it's type:

  • ClassName::FieldName : class public static field and methods
  • ClassInstance.FieldName : accessing a public field (or method) through class reference
  • ClassPointer->FieldName : accessing a public field (or method) dereferencing a class pointer

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();
Heisenbug
  • 38,762
  • 28
  • 132
  • 190
19

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()

RageD
  • 6,693
  • 4
  • 30
  • 37
8

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.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • You helped me a lot but i don't understand why this does not work class Something{ public: static int i; }; Something::i = 0; cout< – Yoda Aug 10 '12 at 14:03
  • 1
    @RobertKilar: That declares but does not *define* `Something::i;`, so you need a separate definition of it, like `int Something::i;`, as I show in the code sample in the answer. Otherwise, the code will compile but not link, because `Something::i` will be an "unresolved external/undefined reference". – Jerry Coffin Aug 10 '12 at 14:06
7

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;
}
Tadeusz Kopec for Ukraine
  • 12,283
  • 6
  • 56
  • 83
Platinum Azure
  • 45,269
  • 12
  • 110
  • 134
3

-> is for pointers to a class instance

. is for class instances

:: is for classnames - for example when using a static member

Gir
  • 839
  • 5
  • 11
2

The '::' is for static members.

Marcin Zaluski
  • 687
  • 5
  • 10
1

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;
}
psx
  • 4,040
  • 6
  • 30
  • 59