c++pointersleveldb

The difference between passing double pointer and pointer as an argument


  1. pass * as a function parameter
#include <iostream>

class A {

 public: 
  A() {}

};


class B : public A{
 public:
  B() {}

};

void foo(A* a) {
 a = new B();

}

void ff() {
  A a;
  foo(&a);
}
  1. pass ** as a function parameter
#include <iostream>

class A {

 public: 
  A() {}

};


class B : public A{
 public:
  B() {}

};

void foo(A** a) {
 *a = new B();

}

void ff() {
  A* a;
  foo(&a);
}

When I see leveldb, I am in a puzzle about this.

The specific code is the following.

https://github.com/google/leveldb/blob/master/db/db_impl.cc#L1537

I think it's ok to use FileLock lock

Then pass &lock to LockFile(const std::string& filename, FileLock* lock)

LockFile function is this


Solution

  • Passing double pointer and just a pointer are not the same

    void foo(A* a) {
     a = new B();
    
    }
    
    1. Change an input pointer to another value. The result will not reflect in the callee ff(). It's merely change the argument.
    void foo(A** a) {
     *a = new B();
    
    }
    
    1. Change a pointer to another pointer and change the value, which is "the another pointer", of this pointer points to . The result will reflect in ff()

    According to the ff(), I assume you have a follow up question which need to operate a after foo() is called. So second one might be a proper way.

    For FileLock, I believe you're referring to this implementation.

    It's using double pointer because it wants to replace the entire content of FileLock.

    Live demo

    Followup: Why it chose using double pointer instead of pass by reference?

    Because reference is not possible to be replaced, my assumption is that it chose it chose to replace the whole content which is simpler than make the implemention complex for re-initialization.