C++ Objects: When should I use pointer or reference

前端 未结 9 1400
情话喂你
情话喂你 2020-12-03 08:45

I can use an object as pointer to it, or its reference. I understand that the difference is that pointers have to be deleted manually, and references remain until they are o

相关标签:
9条回答
  • 2020-12-03 09:06

    As my c++ teacher used to put it, pointers point to the memory location while references are aliases . Hence the main advantage is that they can be used in the same way as the object's name they refer to, but in a scope where the object is not available by passing it there.

    While pointers can be redirected to some other location, references being like constant pointers, can't be redirected. So references cant be used for traversing arrays in a functions etc.

    However a pointer being a separate entity takes up some memory, but the reference being the same as the referred object doesn't take any additional space. This is one of its advantages.

    I have also read that the processing time for references are less,

    as

    int & i = b ;

    i++ ; takes lesser time than

    int * j = b ;

    (*j) ++ ;

    but I am yet to confirm this. If anyone can throw light on this claim it would be great.

    Comments are welcome :)

    0 讨论(0)
  • 2020-12-03 09:11

    A reference is basically a pointer with restrictions (has to be bound on creation, can't be rebound/null). If it makes sense for your code to use these restrictions, then using a reference instead of a pointer allows the compiler to warn you about accidentally violating them.

    It's a lot like the const qualifier: the language could exist without it, it's just there as a bonus feature of sorts that makes it easier to develop safe code.

    0 讨论(0)
  • 2020-12-03 09:14

    Here's another answer (perhaps I should've edited the first one, but since it has a different focus, I thought it would be OK to have them separate).

    When you create a pointer with new, the memory for it is reserved and it persists until you call delete on it - but the identifier's life span is still limited to the code block's end. If you create objects in a function and append them to an external list, the objects may remain safely in the memory after the function returns and you can still reference them without the identifier.

    Here's a (simplified) example from Umbra, a C++ framework I'm developing. There's a list of modules (pointers to objects) stored in the engine. The engine can append an object to that list:

    void UmbraEngine::addModule (UmbraModule * module) {
        modules.push(module);
        module->id = modules.size() - 1;
    }
    

    Retrieve one:

    UmbraModule * UmbraEngine::getModule (int id) {
        for (UmbraModule **it=modules.begin(); it != modules.end(); it++) {
            if ((*it)->id == id) return *it;
        }
    }
    

    Now, I can add and get modules without ever knowing their identifiers:

    int main() {
        UmbraEngine e;
        for (int i = 0; i < 10; i++) {
            e.addModule(new UmbraModule());
        }
        UmbraModule * m = e.getModule(5); //OK
        cout << m << endl; //"0x127f10" or whatever
        for (int j = 0; k < 10; j++) {
            UmbraModule mm; //not a pointer
            e.addModule(&mm);
        }
        m = e.getModule(15);
        cout << m << endl; //{null}
    }
    

    The modules list persists throughout the entire duration of the program, I don't need to care about the modules' life span if they're instantiated with new :). So that's basically it - with pointers, you can have long-lived objects that don't ever need an identifier (or a name, if you will) in order to reference them :).

    Another nice, but very simple example is this:

    void getVal (int * a) {
        *a = 10;
    }
    int main() {
        int b;
        getVal(&b);
        return b;
    }
    
    0 讨论(0)
  • 2020-12-03 09:14

    Let's answer the last question first. Then the first question will make more sense.

    Q: "What is the practical difference[ between a pointer and a reference]?"

    A: A reference is just a local pseudonym for another variable. If you pass a parameter by reference, then that parameter is exactly the same variable as the one that was listed in the calling statement. However, internally there usually is no difference between a pointer and a reference. References provide "syntax sugar" by allowing you to reduce the amount of typing you have to do when all you really wanted was access to a single instance of a given variable.

    Q: "When should I use each of em?"

    A: That's going to be a matter of personal preference. Here's the basic rule I follow. If I'm going to need to manipulate a variable in another scope, and that variable is either an intrinsic type, a class that should be used like an intrinsic type (i.e. std::string, etc...), or a const class instance, then I pass by reference. Otherwise, I'll pass by pointer.

    0 讨论(0)
  • Erm... not exactly. It's the IDENTIFIER that has a scope. When you create an object using new, but its identifier's scope ends, you may end up with a memory leak (or not - depends on what you want to achieve) - the object is in the memory, but you have no means of referencing it anymore.

    The difference is that a pointer is an address in memory, so if you have, say, this code:

    int * a = new int;
    

    a is a pointer. You can print it - and you'll get something like "0x0023F1" - it's just that: an address. It has no value (although some value is stored in the memory at that address).

    int b = 10;
    

    b is a variable with a value of 10. If you print it, you'll get 10.

    Now, if you want a to point to b's address, you can do:

    a = &b; //a points to b's address
    

    or if you want the address pointed by a to have b's value:

    *a = b; //value of b is assigned to the address pointed by a
    

    Please compile this sample and comment/uncomment lines 13 and 14 to see the difference (note WHERE the identifiers point and to WHAT VALUE). I hope the output will be self-explanatory.

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int * a = new int;
        int b = 10;
        cout << "address of a: " << a << endl;
        cout << "address of b: " << &b << endl;
        cout << "value of a: " << *a << endl;
        cout << "value of b: " << b << endl;
        a = &b; //comment/uncomment
        //*a = b; //comment/uncomment
        cout << "address of a: " << a << endl;
        cout << "address of b: " << &b << endl;
        cout << "value of a: " << *a << endl;
        cout << "value of b: " << b << endl;
    }
    
    0 讨论(0)
  • 2020-12-03 09:19

    The thing is you cannot rebind a reference to another object. References are bound compile time and cannot be null or rebound. So pointers aren't redundant if your doubt was that :)

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