When to pass a pointer to pointer as argument to functions in C++?

This question already has an answer here:

  • Are there benefits of passing by pointer over passing by reference in C++? 6 answers

  • C++

    In C++, you can pass by reference, and you do that when you want modifications of the parameter to affect the argument which the caller passed in. That is, passing by reference represents an out or in/out parameter.

    You pass a pointer if the function wants a pointer (obviously), or if you want to signify an optional output parameter - since a reference always has to bind to something, but a pointer can be null.

    By the same logic, pass a pointer to pointer if the function actually needs double pointers (very rare in C++) or if you want to signify an optional [in-]out parameter of pointer type (also quite rare).

    Here are some examples (contrived, but should demonstrate the thing):

    int square(int x)  //pass int by value
    { return x * x; }
    
    void squareRoots(double in, double &plus, double &minus)  //pass double by reference
    {
      plus = sqrt(in);
      minus = -plus;
    }
    
    int toNumber(String s, bool *ok = nullptr)  //optional out parameter
    {
      try {
        int val = s.toNumber();
        if (ok)
          *ok = true;
        return val;
      } catch (NotANumber &) {
        if (ok)
          *ok = false;
        return 0;
      }
    }
    
    int computeAge(Person *person)  //pass pointer by value
    {
      if (!person)
        return -1;
      else
        return now() - person->dateOfBirth();
    }
    
    bool createPerson(Person * &person)  //pass pointer by reference
    {
      if (tooManyPeople())
        return false;
      person = new Person();
      return true;
    }
    
    int sum(int **values)  //pass double pointer by value
    {
      if (!values)
        return 0;
      int res = 0;
      while (*values) {
        res += **values;
        ++values;
      }
      return res;
    }
    
    bool allocate(int ** &arr)  //pass double pointer by reference
    {
      if (!enoughMemory())
        return false;
      arr = new int*[1024];  // array of 1024 pointers to int
      return true;
    }
    
    bool newNode(Node **node = nullptr)  //optional out parameter
    {
      Node *added = dataStructure.createNode();
      if (node)
        *node = added;
      return added;
    }
    

    (Note 1: I am only talking about non-const references here, since that's relevant to the pass by pointer vs. pass by reference. Passing by const-reference usually means "the object is too big to copy needlessly," and does not apply really when pointers to pointers could be involved).

    (Note 2: The above examples are horrible in that they use owning raw pointers, dynamic array allocation etc. In actual C++, you would use smart pointers, std::vector etc. instead. That's why pointers to pointer are rare in C++).


    C

    In C, double pointers are more common, since C does not have a reference type. Therefore, you also use a pointer to "pass by reference." Where & is used in a parameter type in the C++ examples above, * would be used in C (and dereferenced when manipulating the parameter). One example:

    void squareRoots(double in, double *plus, double *minus)  //pass double "by reference"
    {
      *plus = sqrt(in);
      *minus = -*plus;
    }
    

    void SomeFun1(int *);
    void SomeFun2(int **);
    int i;
    int *ptr = &i;
    
    //when you want value of ptr should remain unchanged, but you want to change only value of i, use,
    SomeFun1(int *)
    
    //when you want value of ptr should change. i.e, it should point to some other memory other than i, use,
    SomeFun2(int **);
    

    You pass a pointer to pointer as argument when you want the function to set the value of the pointer.

    You typically do this when the function wants to allocate memory (via malloc or new) and set that value in the argument--then it will be the responsibility of the caller to free it. It is better than returning it as a function return value, because there is no possibility of the caller ignoring the return value by mistake and causing a leak by not freeing it.

    You might also want to use this if you are returning multiple values.

    Another reason to do this is when you want to make want to return the value optionally (ie the pointer to pointer can be NULL). For example, look at strtol() it has an optional endptr.

    Note: you should never set this pointer to a stack variable.

    链接地址: http://www.djcxy.com/p/20718.html

    上一篇: 双指针vs通过引用指针传递

    下一篇: 何时将指针的指针作为参数传递给C ++中的函数?