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

后端 未结 22 1682
予麋鹿
予麋鹿 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:10

    There are many excellent answers already, but let me give you one example:

    I have an simple Item class:

     class Item
        {
        public: 
          std::string name;
          int weight;
          int price;
        };
    

    I make a vector to hold a bunch of them.

    std::vector<Item> inventory;

    I create one million Item objects, and push them back onto the vector. I sort the vector by name, and then do a simple iterative binary search for a particular item name. I test the program, and it takes over 8 minutes to finish executing. Then I change my inventory vector like so:

    std::vector<Item *> inventory;

    ...and create my million Item objects via new. The ONLY changes I make to my code are to use the pointers to Items, excepting a loop I add for memory cleanup at the end. That program runs in under 40 seconds, or better than a 10x speed increase. EDIT: The code is at http://pastebin.com/DK24SPeW With compiler optimizations it shows only a 3.4x increase on the machine I just tested it on, which is still considerable.

    0 讨论(0)
  • 2020-11-22 00:11

    But I can't figure out why should we use it like this?

    I will compare how it works inside the function body if you use:

    Object myObject;
    

    Inside the function, your myObject will get destroyed once this function returns. So this is useful if you don't need your object outside your function. This object will be put on current thread stack.

    If you write inside function body:

     Object *myObject = new Object;
    

    then Object class instance pointed by myObject will not get destroyed once the function ends, and allocation is on the heap.

    Now if you are Java programmer, then the second example is closer to how object allocation works under java. This line: Object *myObject = new Object; is equivalent to java: Object myObject = new Object();. The difference is that under java myObject will get garbage collected, while under c++ it will not get freed, you must somewhere explicitly call `delete myObject;' otherwise you will introduce memory leaks.

    Since c++11 you can use safe ways of dynamic allocations: new Object, by storing values in shared_ptr/unique_ptr.

    std::shared_ptr<std::string> safe_str = make_shared<std::string>("make_shared");
    
    // since c++14
    std::unique_ptr<std::string> safe_str = make_unique<std::string>("make_shared"); 
    

    also, objects are very often stored in containers, like map-s or vector-s, they will automatically manage a lifetime of your objects.

    0 讨论(0)
  • 2020-11-22 00:12

    There are many excellent answers to this question, including the important use cases of forward declarations, polymorphism etc. but I feel a part of the "soul" of your question is not answered - namely what the different syntaxes mean across Java and C++.

    Let's examine the situation comparing the two languages:

    Java:

    Object object1 = new Object(); //A new object is allocated by Java
    Object object2 = new Object(); //Another new object is allocated by Java
    
    object1 = object2; 
    //object1 now points to the object originally allocated for object2
    //The object originally allocated for object1 is now "dead" - nothing points to it, so it
    //will be reclaimed by the Garbage Collector.
    //If either object1 or object2 is changed, the change will be reflected to the other
    

    The closest equivalent to this, is:

    C++:

    Object * object1 = new Object(); //A new object is allocated on the heap
    Object * object2 = new Object(); //Another new object is allocated on the heap
    delete object1;
    //Since C++ does not have a garbage collector, if we don't do that, the next line would 
    //cause a "memory leak", i.e. a piece of claimed memory that the app cannot use 
    //and that we have no way to reclaim...
    
    object1 = object2; //Same as Java, object1 points to object2.
    

    Let's see the alternative C++ way:

    Object object1; //A new object is allocated on the STACK
    Object object2; //Another new object is allocated on the STACK
    object1 = object2;//!!!! This is different! The CONTENTS of object2 are COPIED onto object1,
    //using the "copy assignment operator", the definition of operator =.
    //But, the two objects are still different. Change one, the other remains unchanged.
    //Also, the objects get automatically destroyed once the function returns...
    

    The best way to think of it is that -- more or less -- Java (implicitly) handles pointers to objects, while C++ may handle either pointers to objects, or the objects themselves. There are exceptions to this -- for example, if you declare Java "primitive" types, they are actual values that are copied, and not pointers. So,

    Java:

    int object1; //An integer is allocated on the stack.
    int object2; //Another integer is allocated on the stack.
    object1 = object2; //The value of object2 is copied to object1.
    

    That said, using pointers is NOT necessarily either the correct or the wrong way to handle things; however other answers have covered that satisfactorily. The general idea though is that in C++ you have much more control on the lifetime of the objects, and on where they will live.

    Take home point -- the Object * object = new Object() construct is actually what is closest to typical Java (or C# for that matter) semantics.

    0 讨论(0)
  • 2020-11-22 00:15

    Another good reason to use pointers would be for forward declarations. In a large enough project they can really speed up compile time.

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