Форвард объявил синглтон-класс с функцией друга из класса с форвардным объявлением - PullRequest
0 голосов
/ 26 мая 2019

Я надеюсь, что это связный вопрос ... У меня есть одноэлементное определение класса, например:

#include A.h

class Singleton
{
public:
   // If I change this to a return by pointer, it works fine. But reference gives me problems.
   static Singleton &getInstance();
   Singleton(Singleton const&) = delete;
   void operator=(Singleton const&) = delete;
   ~Singleton();

   friend void A::friendMethodinA();
private:
   Singleton();
   void methodOnlyNeededByA();
}

Определение класса:

Singleton &Singleton::getInstance()
{
   static Singleton instance;
   return instance;
}

Singleton::~Singleton() {}

Singleton::Singleton() {}

void Singleton::methodOnlyNeededByA() { // method body. }

Мое объявление класса A:

#pragma once

class Singleton;

class A
{
public:
   void friendMethodinA();
private:
   // This is what I'm not sure about. I tried
   // Singleton &mSingleton = Singleton::getInstance(); This gives me "use of undefined type 'Singleton'" error. I can't #include Singleton.h because of the friend function.
   // Singleton mSingleton = Singleton::getInstance(); This gives me "cannot be reference -- it is a deleted function" error.
   Singleton mSingleton; // This gives me "A::mSingleton uses undefined class 'Singleton'" error.
}

Мне бы очень хотелось возвращать синглтон по ссылке, а не по указателю b, чтобы избежать нулевых проверок и разыменования указателя при каждом его использовании.Есть ли способ достичь этого без полного рефакторинга, чтобы избежать использования вспомогательных функций?

Целью этой вспомогательной функции является метод methodOnlyNeededByA().Поскольку он должен вызываться только классом A, я не хочу помещать его в открытый интерфейс Singleton.

1 Ответ

5 голосов
/ 26 мая 2019

Вы можете устранить ошибку компилятора:

  1. Использование ссылочного типа в качестве переменной-члена.

    Singleton& mSingleton; 
    

    , а затем

  2. Инициализация его в конструкторе.

Однако, более важный момент, на котором я хочу остановиться: не используйте переменную-член типа Singleton. Когда вам нужно использовать класс, просто позвоните Singleton::getInstance(). Вы можете сохранить ссылку на возвращенный объект в локальной переменной функции или просто использовать возвращенную ссылку.

auto& ref = Singleton::getInsance();
ref.methodOnlyNeededByA();

или

Singleton::getInsance().methodOnlyNeededByA();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...