(->) arrow operator and (.) dot operator , class pointer

后端 未结 6 685
粉色の甜心
粉色の甜心 2021-01-31 21:55

In C++ we know that for a pointer of class we use (->) arrow operator to access the members of that class like here:

#include 
usi         


        
相关标签:
6条回答
  • 2021-01-31 22:15
    myclass *ptr;
    
    ptr = new myclass();     // ptr points to a single object
    ptr->doSomething();      // calls doSomething on the object _pointed to_
    
    ptr = new myclass[10];   // ptr points to multiple objects
    ptr->doSomething();      // calls doSomething on the first object _pointed to_
    (ptr+1)->doSomething();  // calls doSomething on the second object _pointed to_
    
    auto val = ptr[2];       // fetches a reference to the second _object_ to val.
    val.doSomething();       // calls doSomething on the _object reference_ val.
    

    In other words, when indexing the array to fetch the n'th element, you're not fetching a pointer to the n'th element, you're fetching a reference to the actual object, and the members of that need to be accessed using . syntax.

    0 讨论(0)
  • 2021-01-31 22:21

    you should read about difference between pointers and reference that might help you understand your problem.

    In short, the difference is:
    when you declare myclass *p it's a pointer and you can access it's members with ->, because p points to memory location.

    But as soon as you call p=new myclass[10]; p starts to point to array and when you call p[n] you get a reference, which members must be accessed using ..
    But if you use p->member = smth that would be the same as if you called p[0].member = smth, because number in [] is an offset from p to where search for the next array member, for example (p + 5)->member = smth would be same as p[5].member = smth

    0 讨论(0)
  • 2021-01-31 22:27

    Because by using [] like p[3] you are already dereferencing the pointer to array + index shift. After that you have to use ".", since p[3] is an object, not a pointer.

    0 讨论(0)
  • 2021-01-31 22:28

    Note that for a pointer variable x

    myclass *x;
    
    • *x means "get the object that x points to"
    • x->setdata(1, 2) is the same as (*x).setdata(1, 2) and finally
    • x[n] means "get the n-th object in an array".

    So for example x->setdata(1, 2) is the same as x[0].setdata(1, 2).

    0 讨论(0)
  • 2021-01-31 22:32

    Perhaps its insightful to consider that, given

    myclass obj;
    auto p = &obj;  // avoid `new` with plain pointers. That combination is
                   //  safer replaced by unique_ptr or std::vector.
    

    the following will all work and are equivalent:

    p->setdata(5, 6);
    (*p).setdata(5, 6);
    p[0].setdata(5, 6);
    0[p].setdata(5, 6);
    

    Showing that [] is really a pointer-dereferencing operator, just with the extra functionality that you can add offsets into a plain C-array.

    It's generally questionable to use C-arrays in C++ code; the obvious alternative to your example is std::vector:

    std::vector<myclass> array(10);
    

    Here, array[n] can be used much like previously p[n], but

    • You don't get any stupid pointer-ideas, because there are no pointers in the interface
    • You get proper automatic memory management, i.e. when the array goes out of scope it automatically deletes the objects and its memory
    • You can get bounds-checks if you want (array.at(n))
    • You can easily loop over the whole array, with (C++11) for(auto& obj: array){...}.
    0 讨论(0)
  • 2021-01-31 22:33

    After...

    MyClass* p = new myclass[10];
    

    ...p is a pointer to an array of MyClass objects. The "pointer to an array" thing has to be delt with first. Whenever you have a pointer to an array, p[n] effectively gives you a reference to the nth element in the array, so you effectively have a MyClass&. That's why . is then needed to access MyClass members ala p[n].member, and why the pointer-specific -> notation is erroneous in this case....

    Note that p->member (for any member) is still valid and equivalent to p[0].member, so you can only use it for accessing the first element in the array. I strongly recommend you don't use it at all whenever you're in a programmatic context where 'p' is known to be pointer to the array, as it hides the fact that p is an array. Sometimes though you may create another pointer - say q - with the purpose of refering to a single array element - may or may not be [0] - and in those situation's it's fair to use q->member. Variables like q may be used for iteration over the array too. But, sometime you're going to need to delete[] p; - so you won't tend to change p beforehands... you don't want to lose track of the p[0] address or delete[] p; will be Undefined Behaviour (which is allowed to be implementation defined and happens to be on Windows if p still points within the array, but won't be portable).

    0 讨论(0)
提交回复
热议问题