0

I hope this is a coherent question... I have a singleton class definition like:

#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();
}

The class definition is:

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

Singleton::~Singleton() {}

Singleton::Singleton() {}

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

My class A declaration is:

#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.
}

I would really like to return the singleton by reference rather than pointer bto avoid null checks and dereferencing the pointer every time I use it. Is there a way to achieve this without completely refactoring to avoid using friend functions?

The purpose of this friend function is the method methodOnlyNeededByA(). Since it only ever needs to be called by Class A, I do not want to put it in the public interface of the Singleton.

kovac
  • 4,945
  • 9
  • 47
  • 90
  • **"I would really like to return the singleton by reference rather than pointer"** - The code you presented already returns the singleton by reference rather than pointer. – Galik May 26 '19 at 04:56
  • @Galik yes, but this code doesn't compile. I get compiler errors as I mentioned in inline comments. None of the assignment operations I tried in Class A are valid. – kovac May 26 '19 at 04:57
  • Did you try the code from the top answer of this question? https://stackoverflow.com/questions/1008019/c-singleton-design-pattern – Galik May 26 '19 at 04:58
  • @Galik yeah, my singleton implementation is exactly that. It's the friend function that accesses private member function of the singleton that is giving me problems. – kovac May 26 '19 at 05:02
  • 1
    The forward declaration of `class Singleton;` doesn't contain enough information about `Singleton` to instantiate one. All `A` can know at this point is that `Singleton` exists. It doesn't know about any of the methods of `Singleton`, so you can't call them here. You can't include Singleton.h because of circular reference and R Sahu picks it up from there, so I'm not submitting my answer. – user4581301 May 26 '19 at 05:11

1 Answers1

5

You can resolve the compiler error by:

  1. Using a reference type as the member variable.

    Singleton& mSingleton; 
    

    and then

  2. Intializing it in the constructor.

However, the more important point I want to make is: Don't use a member variable of type Singleton. When you need to use the class, simply call Singleton::getInstance(). You can store a reference to the returned object in a function local variable or just use the returned reference.

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

or

Singleton::getInsance().methodOnlyNeededByA();
R Sahu
  • 204,454
  • 14
  • 159
  • 270