What is the difference between "::" "." and "->" in c++

140,967

Solution 1

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

Solution 2

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

Solution 3

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

Solution 4

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.

Solution 5

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;
}
Share:
140,967
Yoda
Author by

Yoda

If you have a question about Bonjour in .NET and AXIS SDK I am the guy. I HATE telerik.

Updated on July 08, 2022

Comments

  • Yoda
    Yoda almost 2 years

    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;
        }
    
    
    
  • Admin
    Admin over 11 years
    @ltjax: References are accessed like normal variables. You can do ref = 2; or ref.x = 5; for an object instance.
  • ltjax
    ltjax over 11 years
    I know, I was just dropping a hint that you might want to add it to 2.
  • Admin
    Admin over 11 years
    You can have a reference to any of them. A reference always keep the same type. It's actually a different subject.
  • ltjax
    ltjax over 11 years
    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.
  • Yoda
    Yoda over 11 years
    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<<Something::i<<endl;
  • Andrew
    Andrew over 11 years
    @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.
  • Jerry Coffin
    Jerry Coffin over 11 years
    @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".
  • David Rodríguez - dribeas
    David Rodríguez - dribeas over 11 years
    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;...
  • Andrew
    Andrew over 11 years
    @DavidRodríguez-dribeas: agree with scope operator. But I prefere not to access static vars/funcs via access operator
  • David Rodríguez - dribeas
    David Rodríguez - dribeas over 11 years
    @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...
  • Yoda
    Yoda over 11 years
    But I canąt get access through AClass::static_field = 0;
  • Jax
    Jax almost 8 years
    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
  • Gewure
    Gewure almost 7 years
    i like the unicode character in your comment, @Yoda :)