Search code examples
c++smart-pointersdereference

C++ - overload structure dereference operator and use it in unique_ptr


I have one implementation class and one wrapper class, and I want to access to implementation class instance through wrapper class with structure dereference (->) operator. So far, no problem.

class Implementation
{
  public:
    doSomething();
}

class Wrapper
{
  public:
    Implementation* operator->() {
      return _implPtr.get();
    }
  private:
    std::shared_ptr<Implementation> _implPtr;
}

It works when I use it like below:

Wrapper wrapper;
wrapper->doSomething();

But when I use the wrapper class with unique_ptr, compiler throws an error:

auto wrapper = std::make_unique<Wrapper>();
wrapper->doSomething();

The error is "'class Wrapper' has no member named 'doSomething'".

How can I access to the implementation class in this scenario?


Solution

  • std::unique_ptr (and std::shared_ptr) has its own operator-> to return the pointer it is holding.

    Your failing code is essentially doing this:

    auto wrapper = std::make_unique<Wrapper>();
    //wrapper->doSomething();
    Wrapper *ptr = wrapper.operator->();
    ptr->doSomething(); // ERROR!
    

    Indeed, there is no doSomething() method in your Wrapper class.

    To do what you are attempting, you need to dereference the Wrapper* pointer to access the actual Wrapper object, then you can call its own operator-> to access its Implementation* pointer, eg:

    auto wrapper = std::make_unique<Wrapper>();
    (*wrapper)->doSomething();
    

    Which is basically doing this:

    auto wrapper = std::make_unique<Wrapper>();
    //(*wrapper)->doSomething();
    Wrapper &ref = wrapper.operator*();
    Implementation *impl = ref.operator->();
    impl->doSomething(); // OK!