Why should I use a pointer rather than the object itself?

后端 未结 22 1648
予麋鹿
予麋鹿 2020-11-21 23:26

I\'m coming from a Java background and have started working with objects in C++. But one thing that occurred to me is that people often use pointers to objects rather than t

22条回答
  •  一向
    一向 (楼主)
    2020-11-22 00:02

    C++ gives you three ways to pass an object: by pointer, by reference, and by value. Java limits you with the latter one (the only exception is primitive types like int, boolean etc). If you want to use C++ not just like a weird toy, then you'd better get to know the difference between these three ways.

    Java pretends that there is no such problem as 'who and when should destroy this?'. The answer is: The Garbage Collector, Great and Awful. Nevertheless, it can't provide 100% protection against memory leaks (yes, java can leak memory). Actually, GC gives you a false sense of safety. The bigger your SUV, the longer your way to the evacuator.

    C++ leaves you face-to-face with object's lifecycle management. Well, there are means to deal with that (smart pointers family, QObject in Qt and so on), but none of them can be used in 'fire and forget' manner like GC: you should always keep in mind memory handling. Not only should you care about destroying an object, you also have to avoid destroying the same object more than once.

    Not scared yet? Ok: cyclic references - handle them yourself, human. And remember: kill each object precisely once, we C++ runtimes don't like those who mess with corpses, leave dead ones alone.

    So, back to your question.

    When you pass your object around by value, not by pointer or by reference, you copy the object (the whole object, whether it's a couple of bytes or a huge database dump - you're smart enough to care to avoid latter, aren't you?) every time you do '='. And to access the object's members, you use '.' (dot).

    When you pass your object by pointer, you copy just a few bytes (4 on 32-bit systems, 8 on 64-bit ones), namely - the address of this object. And to show this to everyone, you use this fancy '->' operator when you access the members. Or you can use the combination of '*' and '.'.

    When you use references, then you get the pointer that pretends to be a value. It's a pointer, but you access the members through '.'.

    And, to blow your mind one more time: when you declare several variables separated by commas, then (watch the hands):

    • Type is given to everyone
    • Value/pointer/reference modifier is individual

    Example:

    struct MyStruct
    {
        int* someIntPointer, someInt; //here comes the surprise
        MyStruct *somePointer;
        MyStruct &someReference;
    };
    
    MyStruct s1; //we allocated an object on stack, not in heap
    
    s1.someInt = 1; //someInt is of type 'int', not 'int*' - value/pointer modifier is individual
    s1.someIntPointer = &s1.someInt;
    *s1.someIntPointer = 2; //now s1.someInt has value '2'
    s1.somePointer = &s1;
    s1.someReference = s1; //note there is no '&' operator: reference tries to look like value
    s1.somePointer->someInt = 3; //now s1.someInt has value '3'
    *(s1.somePointer).someInt = 3; //same as above line
    *s1.somePointer->someIntPointer = 4; //now s1.someInt has value '4'
    
    s1.someReference.someInt = 5; //now s1.someInt has value '5'
                                  //although someReference is not value, it's members are accessed through '.'
    
    MyStruct s2 = s1; //'NO WAY' the compiler will say. Go define your '=' operator and come back.
    
    //OK, assume we have '=' defined in MyStruct
    
    s2.someInt = 0; //s2.someInt == 0, but s1.someInt is still 5 - it's two completely different objects, not the references to the same one
    

提交回复
热议问题