C ++ - перегрузить оператор разыменования структуры и использовать его в unique_ptr - PullRequest
1 голос
/ 14 апреля 2020

У меня есть один класс реализации и один класс-оболочка, и я хочу получить доступ к экземпляру класса реализации через класс-оболочку с оператором разыменования структуры (->). Пока проблем нет.

class Implementation
{
  public:
    doSomething();
}

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

Это работает, когда я использую его, как показано ниже:

Wrapper wrapper;
wrapper->doSomething();

Но когда я использую класс-оболочку с unique_ptr, компилятор выдает ошибку:

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

Ошибка «у класса Wrapper нет члена с именем doSomething».

Как получить доступ к классу реализации в этом сценарии?

1 Ответ

2 голосов
/ 14 апреля 2020

std::unique_ptrstd::shared_ptr) имеет свой собственный operator-> для возврата указателя, который он держит.

Ваш ошибочный код, по сути, делает это:

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

Действительно, в вашем классе Wrapper нет метода doSomething().

Чтобы сделать то, что вы пытаетесь, вам нужно разыменовать указатель Wrapper* для доступа к фактическому Wrapper объект, то вы можете вызвать его собственный operator-> для доступа к его указателю Implementation*, например:

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

, который в основном делает это:

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