0

Today I'm working on a singleton test case in c++. The singleton is working fine but I would like to instantiate the static object when the user try to access a member of it, so if the variable isn't created when we try to access a member of it, it will not crash instead it will simply generate my singleton.

Here's my class.h:

class PDG : public EmployeRH
{
public:
    static void Instantiate(std::string nom, std::string prenom);
   // Current manual instantiation version of the singleton
    PDG* operator->();  
   // This is the line I just added to overload "->" operator ... But it seems it's never called.

    void SePresenter();
    static PDG* _instance;

private:
    PDG();
    ~PDG();
    PDG(std::string nom, std::string prenom);
    int _budget;

};

Methods.cpp

PDG* PDG::_instance=NULL;
PDG::PDG()
{

}

PDG::~PDG()
{

}
PDG::PDG(std::string a_nom, std::string a_prenom):EmployeRH(a_nom,a_prenom)
{
   _budget = 100000;
}

void PDG::Instantiate(std::string a_nom, std::string a_prenom)
{
    cout << "instantiation pdg" << endl;
    if (_instance == NULL)
    {
        _instance = new PDG(a_nom,a_prenom);            
    }
}

PDG* PDG::operator->()
{
    PDG::Instantiate("Unknown", "Unknown");
    return _instance;
}

void PDG::SePresenter()
{
    cout << _nom << " " << _prenom << endl;
}

main.cpp

void main()
{
PDG::_instance->SePresenter();
system("pause");
}

The thing is, it goes directly into "SePresenter()" and not into my overloaded operator "->". If anyone could help it would be greatfull.

Thanks,

Impact

Impact
  • 31
  • 6
  • operator `->` is a bit special. this might help: https://stackoverflow.com/a/4421719/4117728 – 463035818_is_not_an_ai May 08 '20 at 12:29
  • First o all singleton pattern is considered as [anti-pattern](https://stackoverflow.com/a/138012/1387438). Secondly you implemented singleton indirectly and you try to fix your mistake in worst possible way by overloading operator `->`. – Marek R May 08 '20 at 13:07

1 Answers1

1

PDG::_instance is a pointer to PDG so -> simply dereferences the pointer and you can't override the behaviour. To override the -> operator you must call it on the class directly not on a pointer: (*PDG::_instance)->SePresenter(). To preserve your desired syntax and to remove the undefined behaviour from dereferencing the null pointer you can change PDG::_instance into a structure which holds your instance pointer.

#include <string>
#include <iostream>
using namespace std;

struct EmployeRH {
    EmployeRH() {}
    EmployeRH(std::string nom, std::string prenom) {}
    std::string _nom;
    std::string _prenom;
};

class PDG : public EmployeRH {
public:
    static PDG* Instantiate(std::string nom, std::string prenom);
    // Current manual instantiation version of the singleton

    void SePresenter();
    static struct Instance {    
        PDG* operator->()
        {
            return PDG::Instantiate("Unknown", "Unknown");
        }

    } _instance;

private:
    PDG();
    ~PDG();
    PDG(std::string nom, std::string prenom);
    int _budget;
};

PDG::Instance PDG::_instance;
PDG::PDG()
{
}

PDG::~PDG()
{
}
PDG::PDG(std::string a_nom, std::string a_prenom)
    : EmployeRH(a_nom, a_prenom)
{
    _budget = 100000;
}

PDG* PDG::Instantiate(std::string a_nom, std::string a_prenom)
{
    static PDG instance(a_nom, a_prenom);
    cout << "instantiation pdg" << endl;
    return &instance;
}

void PDG::SePresenter()
{
    cout << _nom << " " << _prenom << endl;
}

int main()
{
    PDG::_instance->SePresenter();
    return 0;
}

I've also changed your singleton to use a function static which makes your code thread safe.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • Thanks a lot for this perfect explanation ! :D It's rather easier to just remind me that an operator return of course a pointer and my error was like you said: in the main I was calling "PDG::_instance" instead of "*PDG::_instance" and the operator has to be applied to the whole class and not on a pointer. Thanks again ! – Impact May 08 '20 at 13:28